Messages in this thread Patch in this message | | | Subject | [PATCH] argv_split: Return NULL if argument contains no non-whitespace. | From | Tetsuo Handa <> | Date | Sat, 14 Sep 2013 16:32:19 +0900 |
| |
>From 210f917f3b535bc0d4dcbb20ca4395709e913104 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Date: Sat, 14 Sep 2013 16:24:07 +0900 Subject: [PATCH] argv_split: Return NULL if argument contains no non-whitespace.
I tried
# echo '|' > /proc/sys/kernel/core_pattern
and got
BUG: unable to handle kernel NULL pointer dereference at (null)
upon core dump because helper_argv[0] == NULL at
helper_argv = argv_split(GFP_KERNEL, cn.corename, NULL); call_usermodehelper_setup(helper_argv[0], ...);
if cn.corename == "".
How to check this bug:
# echo '|' > /proc/sys/kernel/core_pattern $ echo 'int main(int argc, char *argv[]) { return *(char *) 0; }' | gcc -x c - -o die $ ulimit -c unlimited $ ./die
This bug seems to exist since 2.6.19 (the version which core dump to pipe was added). Depending on kernel version and config, some side effect might follow immediately after this oops (e.g. kernel panic with 2.6.32-358.18.1.el6).
Assuming that nobody is expecting that argv_split() returns an array with argv[0] == NULL, this patch fixes this bug by changing argv_split() to return NULL if argument contains no non-whitespace.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> --- lib/argv_split.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/lib/argv_split.c b/lib/argv_split.c index e927ed0..5b828d9 100644 --- a/lib/argv_split.c +++ b/lib/argv_split.c @@ -50,7 +50,7 @@ EXPORT_SYMBOL(argv_free); * quote processing is performed. Multiple whitespace characters are * considered to be a single argument separator. The returned array * is always NULL-terminated. Returns NULL on memory allocation - * failure. + * failure or @str being empty or @str containing only white-space. * * The source string at `str' may be undergoing concurrent alteration via * userspace sysctl activity (at least). The argv_split() implementation @@ -68,6 +68,10 @@ char **argv_split(gfp_t gfp, const char *str, int *argcp) return NULL; argc = count_argc(argv_str); + if (!argc) { + kfree(argv_str); + return NULL; + } argv = kmalloc(sizeof(*argv) * (argc + 2), gfp); if (!argv) { kfree(argv_str); -- 1.7.1
| |