lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1234970162-10694-2-git-send-email-kirill@shutemov.name>
Date:	Wed, 18 Feb 2009 17:16:01 +0200
From:	"Kirill A. Shutemov" <kirill@...temov.name>
To:	Andrew Morton <akpm@...ux-foundation.org>
Cc:	linux-kernel@...r.kernel.org, Matthew Garrett <mjg@...hat.com>,
	"Kirill A. Shutemov" <kirill@...temov.name>
Subject: [PATCH 2/3] [RESEND] binfmt_script: rewrite using parse_shell_args()

parse_shell_args() allows to use more than one argument in shebang.

This patch allows to write something like

 #!/usr/bin/env python -c

and it will be parsed according shell rules.

Currently, it interpretes as /usr/bin/env "python -c" and we gets
ENOENT.

Signed-off-by: Kirill A. Shutemov <kirill@...temov.name>
---
 fs/binfmt_script.c |   88 +++++++++++++++++++---------------------------------
 1 files changed, 32 insertions(+), 56 deletions(-)

diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c
index 0834350..ab6a6b2 100644
--- a/fs/binfmt_script.c
+++ b/fs/binfmt_script.c
@@ -1,93 +1,69 @@
 /*
  *  linux/fs/binfmt_script.c
  *
+ *  Copyright (C) 2009  Kirill A. Shutemov
  *  Copyright (C) 1996  Martin von Löwis
  *  original #!-checking implemented by tytso.
  */
 
 #include <linux/module.h>
-#include <linux/string.h>
-#include <linux/stat.h>
-#include <linux/slab.h>
 #include <linux/binfmts.h>
-#include <linux/init.h>
 #include <linux/file.h>
-#include <linux/err.h>
 #include <linux/fs.h>
 
 static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
 {
-	char *cp, *i_name, *i_arg;
 	struct file *file;
-	char interp[BINPRM_BUF_SIZE];
-	int retval;
+	char out[BINPRM_BUF_SIZE];
+	int argc, retval;
 
 	if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') ||
 	    (bprm->recursion_depth > BINPRM_MAX_RECURSION))
 		return -ENOEXEC;
-	/*
-	 * This section does the #! interpretation.
-	 * Sorta complicated, but hopefully it will work.  -TYT
-	 */
 
 	bprm->recursion_depth++;
 	allow_write_access(bprm->file);
 	fput(bprm->file);
 	bprm->file = NULL;
 
-	bprm->buf[BINPRM_BUF_SIZE - 1] = '\0';
-	if ((cp = strchr(bprm->buf, '\n')) == NULL)
-		cp = bprm->buf+BINPRM_BUF_SIZE-1;
-	*cp = '\0';
-	while (cp > bprm->buf) {
-		cp--;
-		if ((*cp == ' ') || (*cp == '\t'))
-			*cp = '\0';
-		else
-			break;
-	}
-	for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
-	if (*cp == '\0') 
-		return -ENOEXEC; /* No interpreter name found */
-	i_name = cp;
-	i_arg = NULL;
-	for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++)
-		/* nothing */ ;
-	while ((*cp == ' ') || (*cp == '\t'))
-		*cp++ = '\0';
-	if (*cp)
-		i_arg = cp;
-	strcpy (interp, i_name);
-	/*
-	 * OK, we've parsed out the interpreter name and
-	 * (optional) argument.
-	 * Splice in (1) the interpreter's name for argv[0]
-	 *           (2) (optional) argument to interpreter
-	 *           (3) filename of shell script (replace argv[0])
-	 *
-	 * This is done in reverse order, because of how the
-	 * user environment and arguments are stored.
-	 */
 	retval = remove_arg_zero(bprm);
 	if (retval)
 		return retval;
+
 	retval = copy_strings_kernel(1, &bprm->interp, bprm);
-	if (retval < 0) return retval; 
+	if (retval < 0)
+		return retval;
 	bprm->argc++;
-	if (i_arg) {
-		retval = copy_strings_kernel(1, &i_arg, bprm);
-		if (retval < 0) return retval; 
-		bprm->argc++;
+
+	bprm->buf[BINPRM_BUF_SIZE - 1] = '\0';
+
+	argc = parse_shell_args(bprm->buf+2, out, BINPRM_BUF_SIZE);
+
+	if (!argc)
+		return -ENOEXEC;
+
+	{
+		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;
 	}
-	retval = copy_strings_kernel(1, &i_name, bprm);
-	if (retval) return retval; 
-	bprm->argc++;
-	bprm->interp = interp;
+
+	bprm->interp = out;
 
 	/*
 	 * OK, now restart the process with the interpreter's dentry.
 	 */
-	file = open_exec(interp);
+	file = open_exec(out);
 	if (IS_ERR(file))
 		return PTR_ERR(file);
 
@@ -95,7 +71,7 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
 	retval = prepare_binprm(bprm);
 	if (retval < 0)
 		return retval;
-	return search_binary_handler(bprm,regs);
+	return search_binary_handler(bprm, regs);
 }
 
 static struct linux_binfmt script_format = {
-- 
1.6.1.3.GIT

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ