Commit 867c7a0a authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] binfmt_script argv[0] fix

From: Arun Sharma <arun.sharma@intel.com>

A script such as

  #!/bin/foo.bar
  ...

where /bin/foo.bar is handled by binfmt_misc, is not handled correctly i.e.
the interpreter of foo.bar doesn't receive the correct arguments.

The binfmt_misc handler requires that bprm->filename is appropriately
filled so that the argv[1] could be correctly passed to the interpreter.

However, binfmt_script, as it exists today doesn't populate bprm->filename
correctly.

Another motivation for this patch is the output of ps.  Emulators which use
binfmt_misc may want to keep the output of ps consistent with native
execution.  This requires preserving bprm->filename.  The attached patch
guarantees this even if we have to go through several binfmt handlers
(think of finite loops involving binfmt_script and binfmt_misc).
parent f4f980fb
......@@ -62,7 +62,7 @@ static int entry_count;
*/
static Node *check_file(struct linux_binprm *bprm)
{
char *p = strrchr(bprm->filename, '.');
char *p = strrchr(bprm->interp, '.');
struct list_head *l;
list_for_each(l, &entries) {
......@@ -127,13 +127,13 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
remove_arg_zero(bprm);
}
retval = copy_strings_kernel(1, &bprm->filename, bprm);
retval = copy_strings_kernel(1, &bprm->interp, bprm);
if (retval < 0) goto _ret;
bprm->argc++;
retval = copy_strings_kernel(1, &iname_addr, bprm);
if (retval < 0) goto _ret;
bprm->argc++;
bprm->filename = iname; /* for binfmt_script */
bprm->interp = iname; /* for binfmt_script */
file = open_exec(iname);
retval = PTR_ERR(file);
......
......@@ -69,7 +69,7 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
* user environment and arguments are stored.
*/
remove_arg_zero(bprm);
retval = copy_strings_kernel(1, &bprm->filename, bprm);
retval = copy_strings_kernel(1, &bprm->interp, bprm);
if (retval < 0) return retval;
bprm->argc++;
if (i_arg) {
......@@ -80,6 +80,8 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
retval = copy_strings_kernel(1, &i_name, bprm);
if (retval) return retval;
bprm->argc++;
bprm->interp = interp;
/*
* OK, now restart the process with the interpreter's dentry.
*/
......
......@@ -1053,6 +1053,7 @@ int do_execve(char * filename,
bprm.file = file;
bprm.filename = filename;
bprm.interp = filename;
bprm.sh_bang = 0;
bprm.loader = 0;
bprm.exec = 0;
......
......@@ -31,7 +31,10 @@ struct linux_binprm{
kernel_cap_t cap_inheritable, cap_permitted, cap_effective;
void *security;
int argc, envc;
char * filename; /* Name of binary */
char * filename; /* Name of binary as seen by procps */
char * interp; /* Name of the binary really executed. Most
of the time same as filename, but could be
different for binfmt_{misc,script} */
unsigned long loader, exec;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment