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; ...@@ -62,7 +62,7 @@ static int entry_count;
*/ */
static Node *check_file(struct linux_binprm *bprm) static Node *check_file(struct linux_binprm *bprm)
{ {
char *p = strrchr(bprm->filename, '.'); char *p = strrchr(bprm->interp, '.');
struct list_head *l; struct list_head *l;
list_for_each(l, &entries) { list_for_each(l, &entries) {
...@@ -127,13 +127,13 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs) ...@@ -127,13 +127,13 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) { if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
remove_arg_zero(bprm); 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; if (retval < 0) goto _ret;
bprm->argc++; bprm->argc++;
retval = copy_strings_kernel(1, &iname_addr, bprm); retval = copy_strings_kernel(1, &iname_addr, bprm);
if (retval < 0) goto _ret; if (retval < 0) goto _ret;
bprm->argc++; bprm->argc++;
bprm->filename = iname; /* for binfmt_script */ bprm->interp = iname; /* for binfmt_script */
file = open_exec(iname); file = open_exec(iname);
retval = PTR_ERR(file); retval = PTR_ERR(file);
......
...@@ -69,7 +69,7 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs) ...@@ -69,7 +69,7 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
* user environment and arguments are stored. * user environment and arguments are stored.
*/ */
remove_arg_zero(bprm); 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; if (retval < 0) return retval;
bprm->argc++; bprm->argc++;
if (i_arg) { if (i_arg) {
...@@ -80,6 +80,8 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs) ...@@ -80,6 +80,8 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
retval = copy_strings_kernel(1, &i_name, bprm); retval = copy_strings_kernel(1, &i_name, bprm);
if (retval) return retval; if (retval) return retval;
bprm->argc++; bprm->argc++;
bprm->interp = interp;
/* /*
* OK, now restart the process with the interpreter's dentry. * OK, now restart the process with the interpreter's dentry.
*/ */
......
...@@ -1053,6 +1053,7 @@ int do_execve(char * filename, ...@@ -1053,6 +1053,7 @@ int do_execve(char * filename,
bprm.file = file; bprm.file = file;
bprm.filename = filename; bprm.filename = filename;
bprm.interp = filename;
bprm.sh_bang = 0; bprm.sh_bang = 0;
bprm.loader = 0; bprm.loader = 0;
bprm.exec = 0; bprm.exec = 0;
......
...@@ -31,7 +31,10 @@ struct linux_binprm{ ...@@ -31,7 +31,10 @@ struct linux_binprm{
kernel_cap_t cap_inheritable, cap_permitted, cap_effective; kernel_cap_t cap_inheritable, cap_permitted, cap_effective;
void *security; void *security;
int argc, envc; 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; 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