[PATCH] kexec.c: workaround getline and fscanf to make it *libc agnostic. Tested against klibc and dietlibc.
Simon Horman
horms at verge.net.au
Wed Nov 25 19:14:10 EST 2009
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 at gmail.com>
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;
}
More information about the kexec
mailing list