[PATCH] multiboot: fix crash on NULL kernel command line

Ameya Palande 2ameya at gmail.com
Thu Feb 5 13:36:24 PST 2015


If "--command-line" option is not specified, then kexec segfaults while
dereferencing NULL command line string pointer. While we are at it, also
fix indentation and use '{' and '}' consistently.

Signed-off-by: Ameya Palande <2ameya at gmail.com>
---
 kexec/arch/i386/kexec-multiboot-x86.c | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/kexec/arch/i386/kexec-multiboot-x86.c b/kexec/arch/i386/kexec-multiboot-x86.c
index fce7f05..0dbac70 100644
--- a/kexec/arch/i386/kexec-multiboot-x86.c
+++ b/kexec/arch/i386/kexec-multiboot-x86.c
@@ -169,8 +169,7 @@ int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len,
 	static const char short_options[] = KEXEC_ARCH_OPT_STR "";
 	
 	/* Probe for the MB header if it's not already found */
-	if (mbh == NULL && multiboot_x86_probe(buf, len) != 1) 
-	{
+	if (mbh == NULL && multiboot_x86_probe(buf, len) != 1) {
 		fprintf(stderr, "Cannot find a loadable multiboot header.\n");
 		return -1;
 	}
@@ -180,8 +179,7 @@ int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len,
 	modules = 0;
 	mod_command_line_space = 0;
 	result = 0;
-	while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1)
-	{
+	while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) {
 		switch(opt) {
 		default:
 			/* Ignore core options */
@@ -192,7 +190,7 @@ int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len,
 			append = optarg;
 			break;
 		case OPT_REUSE_CMDLINE:
-			tmp_cmdline = get_command_line();
+			command_line = get_command_line();
 			break;
 		case OPT_MOD:
 			modules++;
@@ -201,11 +199,17 @@ int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len,
 		}
 	}
 	imagename = argv[optind];
-	command_line = concat_cmdline(tmp_cmdline, append);
+
+	/* Final command line = imagename + <OPT_REUSE_CMDLINE> + <OPT_CL> */
+	tmp_cmdline = concat_cmdline(command_line, append);
+	if (command_line) {
+		free(command_line);
+	}
+	command_line = concat_cmdline(imagename, tmp_cmdline);
 	if (tmp_cmdline) {
 		free(tmp_cmdline);
 	}
-	command_line_len = strlen(command_line) + strlen(imagename) + 2;
+	command_line_len = strlen(command_line) + 1;
 	
 	/* Load the ELF executable */
 	elf_exec_build_load(info, &ehdr, buf, len, 0);
@@ -232,8 +236,7 @@ int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len,
 	mbi_buf = xmalloc(mbi_bytes);
 	mbi = mbi_buf;
 	memset(mbi, 0, sizeof(*mbi));
-	sprintf(((char *)mbi) + sizeof(*mbi), "%s %s",
-		imagename, command_line);
+	sprintf(((char *)mbi) + sizeof(*mbi), "%s", command_line);
 	sprintf(((char *)mbi) + sizeof(*mbi) + command_line_len, "%s",
 		BOOTLOADER " " BOOTLOADER_VERSION);
 	mbi->flags = MB_INFO_CMDLINE | MB_INFO_BOOT_LOADER_NAME;
@@ -274,9 +277,9 @@ int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len,
 			if ((range[i].start <= 0x100000)
 			    && (range[i].end > mem_upper + 0x100000))
 				mem_upper = range[i].end - 0x100000;
+		} else {
+			mmap[i].Type = 0xbad;  /* Not RAM */
 		}
-		else
-		mmap[i].Type = 0xbad;  /* Not RAM */
 	}
 
 	if (mbh->flags & MULTIBOOT_MEMORY_INFO) { 
@@ -324,8 +327,7 @@ int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len,
 		/* Go back and parse the module command lines */
 		optind = opterr = 1;
 		while((opt = getopt_long(argc, argv, 
-					 short_options, options, 0)) != -1)
-		{
+					 short_options, options, 0)) != -1) {
 			if (opt != OPT_MOD) continue;
 
 			/* Split module filename from command line */
@@ -358,14 +360,13 @@ int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len,
 			mod_clp += strlen(mod_clp) + 1;
 			modp++;
 		}
-		
 	}
 
 	/* Find a place for the MBI to live */
 	if (sort_segments(info) < 0) {
-                result = -1;
+		result = -1;
 		goto out;
-        }
+	}
 	mbi_base = add_buffer(info,
 		mbi_buf, mbi_bytes, mbi_bytes, 4, 0, 0xFFFFFFFFUL, 1);
 		
@@ -394,4 +395,3 @@ out:
 /*
  *  EOF (kexec-multiboot-x86.c)
  */
-
-- 
1.8.3.1




More information about the kexec mailing list