On Thu, Nov 26, 2009 at 12:37:08AM +0100, Bernhard Walle wrote: > Simon Horman schrieb: > > > > + > > + if ( NULL == p) > > + return -1; > > Wouldn't that be better 'p == NULL'? Agreed > > + ret = strtol(line, &p, 10); > > + > > + /* Too long */ > > + if (ret > INT_MAX) > > + return -1; > > An integer that can be represented in 2 (strlen("__\0")==3) cannot be > larger than INT_MAX on any platform I can imagine. ;-) True, though it doesn't seem outrageous to check anyway. Perhaps the string format will change in future. ---------------------------------------------------------------------- From: Andrea Adami <andrea.adami@xxxxxxxxx> To: kexec at lists.infradead.org Subject: [PATCH] kexec.c: workaround getline and fscanf to make it *libc agnostic. Tested against klibc and dietlibc. Based on a patch by Andrea Adami and Yuri Bushmelev I have: * Cleaned up indentation * Rearranged the logic in get_command_line() * Increased the buffer for reading the command line from 1024 to 2048 bytes as this is now possible on x86 Only compile tested against glibc. Cc: Andrea Adami <andrea.adami at gmail.com> Cc: Yuri Bushmelev <jay4mail at gmail.com> Cc: Bernhard Walle <bernhard at bwalle.de> Signed-off-by: Simon Horman <horms at verge.net.au> Index: kexec-tools/kexec/kexec.c =================================================================== --- kexec-tools.orig/kexec/kexec.c 2009-11-26 10:10:01.000000000 +1100 +++ kexec-tools/kexec/kexec.c 2009-11-26 11:13:46.000000000 +1100 @@ -933,15 +933,32 @@ void usage(void) static int kexec_loaded(void) { - int ret; + long ret = -1; FILE *fp; + char *p; + char line[3]; fp = fopen("/sys/kernel/kexec_loaded", "r"); if (fp == NULL) return -1; - fscanf(fp, "%d", &ret); + + p = fgets(line, sizeof(line), fp); fclose(fp); - return ret; + + if (p == NULL) + return -1; + + ret = strtol(line, &p, 10); + + /* Too long */ + if (ret > INT_MAX) + return -1; + + /* No digits were found */ + if (p == line) + return -1; + + return (int)ret; } /* @@ -989,24 +1006,28 @@ static void remove_parameter(char *line, char *get_command_line(void) { FILE *fp; - size_t len; - char *line = NULL; + char *line; + const int sizeof_line = 2048; + + line = malloc(sizeof_line); + if (line == NULL) + die("Could not allocate memory to read /proc/cmdline."); fp = fopen("/proc/cmdline", "r"); if (!fp) - die("Could not read /proc/cmdline."); - getline(&line, &len, fp); + die("Could not open /proc/cmdline."); + + if (fgets(line, sizeof_line, fp) == NULL) + die("Can't read /proc/cmdline."); + fclose(fp); - if (line) { - /* strip newline */ - *(line + strlen(line) - 1) = 0; - - remove_parameter(line, "BOOT_IMAGE"); - if (kexec_flags & KEXEC_ON_CRASH) - remove_parameter(line, "crashkernel"); - } else - line = strdup(""); + /* strip newline */ + line[strlen(line) - 1] = '\0'; + + remove_parameter(line, "BOOT_IMAGE"); + if (kexec_flags & KEXEC_ON_CRASH) + remove_parameter(line, "crashkernel"); return line; }