
From: Tom Rini <trini@kernel.crashing.org>

OK.  After looking harder at the console= stuff, here's what I'm
proposing (and, FWIW, I hope Rusty is right and all of the parse_arg
stuff can be called very early).
- Drop early-param-fixes.patch (or replace with this)

From: Tom Rini <trini@kernel.crashing.org>
- In parse_early_options, find the end of each argument (' ') and assume
  if no space, we are the last arg.  After a sucessful call,
  move past the argument as it might have been spliced up with NULs.
- In console_setup, ensure that name and options are NUL-terminated.
- Document the restrictions on __early_param calls.


---

 /dev/null                    |    0 
 25-akpm/include/linux/init.h |    5 ++++-
 25-akpm/init/main.c          |   25 +++++++++++++++++++------
 25-akpm/kernel/printk.c      |    8 ++++++--
 4 files changed, 29 insertions(+), 9 deletions(-)

diff -puN include/linux/init.h~early-param-fixes-2 include/linux/init.h
--- 25/include/linux/init.h~early-param-fixes-2	2004-03-31 22:35:18.862124464 -0800
+++ 25-akpm/include/linux/init.h	2004-03-31 22:35:18.868123552 -0800
@@ -68,7 +68,10 @@ extern initcall_t __con_initcall_start, 
 extern initcall_t __security_initcall_start, __security_initcall_end;
 
 /*
- * Early command line parameters.
+ * Early command line parameters.  We do not allow for spaces in
+ * our arguments.  Functions are allowed to fail (negative return
+ * value) but must ensure the arg is unchanged, and can only splice
+ * the arg up, and not rewrite it.
  */
 struct early_params {
 	const char *arg;
diff -L include/linux/init.h.orig -puN /dev/null /dev/null
diff -puN init/main.c~early-param-fixes-2 init/main.c
--- 25/init/main.c~early-param-fixes-2	2004-03-31 22:35:18.863124312 -0800
+++ 25-akpm/init/main.c	2004-03-31 22:35:34.021819840 -0800
@@ -419,18 +419,31 @@ void __init parse_early_options(char **c
 	for (;;) {
 		if (c == ' ') {
 			struct early_params *p;
+			char *before = from;
 
 			for (p = &__early_begin; p < &__early_end; p++) {
 				int len = strlen(p->arg);
 
 				if (memcmp(from, p->arg, len) == 0) {
-					if (to != *cmdline_p)
-						to -= 1;
-					from += len;
-					p->fn(from);
+					char *after;
 
-					while (*from != ' ' && *from != '\0')
-						from++;
+					from += len;
+					/* Find the end of this arg, and
+					 * no spaces allowed in an arg. */
+					after = strchr(from, ' ');
+					if (p->fn(from) < 0) {
+						from = before;
+						break;
+					}
+
+					/* Advance the string. */
+					if (after) {
+						*after = ' ';
+						from = after;
+					} else {
+						while (*from != '\0')
+							from++;
+					}
 					break;
 				}
 			}
diff -puN kernel/printk.c~early-param-fixes-2 kernel/printk.c
--- 25/kernel/printk.c~early-param-fixes-2	2004-03-31 22:35:18.865124008 -0800
+++ 25-akpm/kernel/printk.c	2004-03-31 22:35:18.870123248 -0800
@@ -123,7 +123,8 @@ static int __init console_setup(char *st
 	int idx;
 
 	/*
-	 *	Decode str into name, index, options.
+	 *	Decode str into name, index, options, ensure name and
+	 *	options are NUL-terminated.
 	 */
 	if (str[0] >= '0' && str[0] <= '9') {
 		strcpy(name, "ttyS");
@@ -131,8 +132,11 @@ static int __init console_setup(char *st
 	} else
 		strncpy(name, str, sizeof(name) - 1);
 	name[sizeof(name) - 1] = 0;
-	if ((options = strchr(str, ',')) != NULL)
+	if ((options = strchr(str, ',')) != NULL) {
 		*(options++) = 0;
+		if ((s = strchr(options, ' ')) != NULL)
+			*s = 0;
+	}
 #ifdef __sparc__
 	if (!strcmp(str, "ttya"))
 		strcpy(name, "ttyS0");
diff -L kernel/printk.c.orig -puN /dev/null /dev/null

_
