From c59af3ab34f41f259eb2f019e9f5f9ad3229893f Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Tue, 2 Feb 2010 14:42:02 +1100 Subject: don't leak in concat_cmdline Cc: Eric W. Biederman Signed-off-by: Simon Horman --- kexec/arch/i386/kexec-bzImage.c | 5 +++-- kexec/arch/i386/kexec-elf-x86.c | 9 +++++++-- kexec/arch/i386/kexec-multiboot-x86.c | 5 +++-- kexec/arch/x86_64/kexec-elf-x86_64.c | 9 +++++++-- kexec/kexec.c | 20 ++++++++++++++------ kexec/kexec.h | 2 +- 6 files changed, 35 insertions(+), 15 deletions(-) diff --git a/kexec/arch/i386/kexec-bzImage.c b/kexec/arch/i386/kexec-bzImage.c index 21c1ddf..825beee 100644 --- a/kexec/arch/i386/kexec-bzImage.c +++ b/kexec/arch/i386/kexec-bzImage.c @@ -332,8 +332,8 @@ int do_bzImage_load(struct kexec_info *info, int bzImage_load(int argc, char **argv, const char *buf, off_t len, struct kexec_info *info) { - const char *command_line = NULL, *append = NULL; - const char *ramdisk; + char *command_line = NULL; + const char *ramdisk, *append = NULL; char *ramdisk_buf; off_t ramdisk_length; int command_line_len; @@ -406,5 +406,6 @@ int bzImage_load(int argc, char **argv, const char *buf, off_t len, ramdisk_buf, ramdisk_length, real_mode_entry, debug); + free(command_line); return result; } diff --git a/kexec/arch/i386/kexec-elf-x86.c b/kexec/arch/i386/kexec-elf-x86.c index aaf46ba..2e394e9 100644 --- a/kexec/arch/i386/kexec-elf-x86.c +++ b/kexec/arch/i386/kexec-elf-x86.c @@ -88,8 +88,8 @@ int elf_x86_load(int argc, char **argv, const char *buf, off_t len, struct kexec_info *info) { struct mem_ehdr ehdr; - const char *command_line = NULL, *append = NULL; - char *modified_cmdline; + char *command_line = NULL, *modified_cmdline = NULL; + const char *append = NULL; int command_line_len; int modified_cmdline_len; const char *ramdisk; @@ -264,8 +264,10 @@ int elf_x86_load(int argc, char **argv, const char *buf, off_t len, if (rc < 0) return -1; /* Use new command line. */ + free(command_line); command_line = modified_cmdline; command_line_len = strlen(modified_cmdline) + 1; + modified_cmdline = NULL; } /* Tell the kernel what is going on */ @@ -288,5 +290,8 @@ int elf_x86_load(int argc, char **argv, const char *buf, off_t len, else { die("Unknown argument style\n"); } + + free(command_line); + free(modified_cmdline); return 0; } diff --git a/kexec/arch/i386/kexec-multiboot-x86.c b/kexec/arch/i386/kexec-multiboot-x86.c index 9817ba9..bb77dbc 100644 --- a/kexec/arch/i386/kexec-multiboot-x86.c +++ b/kexec/arch/i386/kexec-multiboot-x86.c @@ -147,8 +147,8 @@ int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len, unsigned long mbi_base; struct entry32_regs regs; size_t mbi_bytes, mbi_offset; - const char *command_line=NULL, *append=NULL; - char *imagename, *cp; + char *command_line = NULL; + char *imagename, *cp, *append = NULL;; struct memory_range *range; int ranges; struct AddrRangeDesc *mmap; @@ -389,6 +389,7 @@ int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len, regs.eip = ehdr.e_entry; elf_rel_set_symbol(&info->rhdr, "entry32_regs", ®s, sizeof(regs)); + free(command_line); return 0; } diff --git a/kexec/arch/x86_64/kexec-elf-x86_64.c b/kexec/arch/x86_64/kexec-elf-x86_64.c index 901262f..c7a1bd8 100644 --- a/kexec/arch/x86_64/kexec-elf-x86_64.c +++ b/kexec/arch/x86_64/kexec-elf-x86_64.c @@ -87,8 +87,8 @@ int elf_x86_64_load(int argc, char **argv, const char *buf, off_t len, struct kexec_info *info) { struct mem_ehdr ehdr; - const char *command_line = NULL, *append = NULL; - char *modified_cmdline; + const char *append = NULL; + char *command_line = NULL, *modified_cmdline; int command_line_len; int modified_cmdline_len; const char *ramdisk; @@ -249,8 +249,10 @@ int elf_x86_64_load(int argc, char **argv, const char *buf, off_t len, if (rc < 0) return -1; /* Use new command line. */ + free(command_line); command_line = modified_cmdline; command_line_len = strlen(modified_cmdline) + 1; + modified_cmdline = NULL; } /* Tell the kernel what is going on */ @@ -273,5 +275,8 @@ int elf_x86_64_load(int argc, char **argv, const char *buf, off_t len, else { die("Unknown argument style\n"); } + + free(command_line); + free(modified_cmdline); return 0; } diff --git a/kexec/kexec.c b/kexec/kexec.c index f4c22a6..db73b0e 100644 --- a/kexec/kexec.c +++ b/kexec/kexec.c @@ -62,6 +62,14 @@ void die(char *fmt, ...) exit(1); } +char *xstrdup(const char *str) +{ + char *new = strdup(str); + if (!new) + die("Cannot strdup \"%s\": %s\n", + str, strerror(errno)); + return new; +} void *xmalloc(size_t size) { @@ -994,15 +1002,15 @@ void check_reuse_initrd(void) free(line); } -const char *concat_cmdline(const char *base, const char *append) +char *concat_cmdline(const char *base, const char *append) { - const char *cmdline; + char *cmdline; if (!base && !append) return NULL; - if (!base) - return append; - if (!append) - return base; + if (append) + return xstrdup(append); + if (base) + return xstrdup(base); cmdline = xmalloc(strlen(base) + 1 + strlen(append) + 1); strcpy(cmdline, base); strcat(cmdline, " "); diff --git a/kexec/kexec.h b/kexec/kexec.h index ebc5a95..5f00525 100644 --- a/kexec/kexec.h +++ b/kexec/kexec.h @@ -261,6 +261,6 @@ static inline int __attribute__ ((format (printf, 1, 2))) dbgprintf(const char *fmt, ...) {return 0;} #endif -const char *concat_cmdline(const char *base, const char *append); +char *concat_cmdline(const char *base, const char *append); #endif /* KEXEC_H */ -- cgit