Messages in this thread Patch in this message | | | From | "Kirill A. Shutemov" <> | Subject | [PATCH 3/3] [RESEND] binfmt_misc.c: Allow arguments in interpreter string | Date | Wed, 18 Feb 2009 17:16:02 +0200 |
| |
Use parse_shell_args() to parse interpreter string. It allows to pass arguments to interpreter.
Now we can drop dummy wrappers around interpreters.
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name> --- fs/binfmt_misc.c | 46 +++++++++++++++++++++++++++++----------------- 1 files changed, 29 insertions(+), 17 deletions(-)
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index c4e8353..fadb29d 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -14,6 +14,7 @@ * 1997-06-30 minor cleanup * 1997-08-09 removed extension stripping, locking cleanup * 2001-02-28 AV: rewritten into something that resembles C. Original didn't. + * 2009-02-03 Allow arguments in interpreter string */ #include <linux/module.h> @@ -50,7 +51,7 @@ typedef struct { int size; /* size of magic/mask */ char *magic; /* magic or filename extension */ char *mask; /* mask, NULL for exact match */ - char *interpreter; /* filename of interpreter */ + char *command; /* command to interprete the file */ char *name; struct dentry *dentry; } Node; @@ -107,8 +108,8 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs) { Node *fmt; struct file * interp_file = NULL; - char iname[BINPRM_BUF_SIZE]; - char *iname_addr = iname; + char out[BINPRM_BUF_SIZE]; + int argc = 0; int retval; int fd_binary = -1; @@ -120,13 +121,14 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs) if (bprm->recursion_depth > BINPRM_MAX_RECURSION) goto _ret; - /* to keep locking time low, we copy the interpreter string */ + /* to keep locking time low, we copy the command string */ read_lock(&entries_lock); fmt = check_file(bprm); if (fmt) - strlcpy(iname, fmt->interpreter, BINPRM_BUF_SIZE); + argc = parse_shell_args(fmt->command, out, BINPRM_BUF_SIZE); read_unlock(&entries_lock); - if (!fmt) + + if (!argc) goto _ret; if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) { @@ -170,15 +172,25 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs) goto _error; bprm->argc++; - /* add the interp as argv[0] */ - retval = copy_strings_kernel (1, &iname_addr, bprm); - if (retval < 0) - goto _error; - bprm->argc ++; + { + char *argv[argc]; + char *out_p = out; + int i; + + for(i=0; i < argc; i++) { + argv[i] = out_p; + out_p += strlen(out_p) + 1; + } + + retval = copy_strings_kernel(argc, argv, bprm); + if (retval) + return retval; + bprm->argc += argc; + } - bprm->interp = iname; /* for binfmt_script */ + bprm->interp = out; /* for binfmt_script */ - interp_file = open_exec (iname); + interp_file = open_exec (out); retval = PTR_ERR (interp_file); if (IS_ERR (interp_file)) goto _error; @@ -287,7 +299,7 @@ static char * check_special_flags (char * sfs, Node * e) } /* * This registers a new binary format, it recognises the syntax - * ':name:type:offset:magic:mask:interpreter:flags' + * ':name:type:offset:magic:mask:command:flags' * where the ':' is the IFS, that can be chosen with the first char */ static Node *create_entry(const char __user *buffer, size_t count) @@ -379,12 +391,12 @@ static Node *create_entry(const char __user *buffer, size_t count) goto Einval; *p++ = '\0'; } - e->interpreter = p; + e->command = p; p = strchr(p, del); if (!p) goto Einval; *p++ = '\0'; - if (!e->interpreter[0]) + if (!e->command[0]) goto Einval; @@ -448,7 +460,7 @@ static void entry_status(Node *e, char *page) return; } - sprintf(page, "%s\ninterpreter %s\n", status, e->interpreter); + sprintf(page, "%s\ninterpreter %s\n", status, e->command); dp = page + strlen(page); /* print the special flags */ -- 1.6.1.3.GIT
| |