summaryrefslogtreecommitdiffstats
path: root/kernel/debug
diff options
context:
space:
mode:
authorJason Wessel <jason.wessel@windriver.com>2013-02-03 16:32:28 +0100
committerJason Wessel <jason.wessel@windriver.com>2013-03-02 15:52:18 +0100
commit4eb7a66d9410927fb8fbafad8b8298b627cdd128 (patch)
treec16c9844a02ac61b1d4aac613f18f3157620de46 /kernel/debug
parentFixed dead ifdef block by adding missing Kconfig option. (diff)
downloadlinux-4eb7a66d9410927fb8fbafad8b8298b627cdd128.tar.xz
linux-4eb7a66d9410927fb8fbafad8b8298b627cdd128.zip
kdb: Fix overlap in buffers with strcpy
Maxime reported that strcpy(s->usage, s->usage+1) has no definitive guarantee that it will work on all archs the same way when you have overlapping memory. The fix is simple for the kdb code because we still have the original string memory in the function scope, so we just have to use that as the argument instead. Reported-by: Maxime Villard <rustyBSD@gmx.fr> Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Diffstat (limited to 'kernel/debug')
-rw-r--r--kernel/debug/kdb/kdb_main.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
index 437b74ddca81..de22c8cc6c30 100644
--- a/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -683,32 +683,44 @@ static int kdb_defcmd(int argc, const char **argv)
return KDB_ARGCOUNT;
defcmd_set = kmalloc((defcmd_set_count + 1) * sizeof(*defcmd_set),
GFP_KDB);
- if (!defcmd_set) {
- kdb_printf("Could not allocate new defcmd_set entry for %s\n",
- argv[1]);
- defcmd_set = save_defcmd_set;
- return KDB_NOTIMP;
- }
+ if (!defcmd_set)
+ goto fail_defcmd;
memcpy(defcmd_set, save_defcmd_set,
defcmd_set_count * sizeof(*defcmd_set));
- kfree(save_defcmd_set);
s = defcmd_set + defcmd_set_count;
memset(s, 0, sizeof(*s));
s->usable = 1;
s->name = kdb_strdup(argv[1], GFP_KDB);
+ if (!s->name)
+ goto fail_name;
s->usage = kdb_strdup(argv[2], GFP_KDB);
+ if (!s->usage)
+ goto fail_usage;
s->help = kdb_strdup(argv[3], GFP_KDB);
+ if (!s->help)
+ goto fail_help;
if (s->usage[0] == '"') {
- strcpy(s->usage, s->usage+1);
+ strcpy(s->usage, argv[2]+1);
s->usage[strlen(s->usage)-1] = '\0';
}
if (s->help[0] == '"') {
- strcpy(s->help, s->help+1);
+ strcpy(s->help, argv[3]+1);
s->help[strlen(s->help)-1] = '\0';
}
++defcmd_set_count;
defcmd_in_progress = 1;
+ kfree(save_defcmd_set);
return 0;
+fail_help:
+ kfree(s->usage);
+fail_usage:
+ kfree(s->name);
+fail_name:
+ kfree(defcmd_set);
+fail_defcmd:
+ kdb_printf("Could not allocate new defcmd_set entry for %s\n", argv[1]);
+ defcmd_set = save_defcmd_set;
+ return KDB_NOTIMP;
}
/*