aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/debug/kdb/kdb_main.c
diff options
context:
space:
mode:
authorJason Wessel <jason.wessel@windriver.com>2013-02-03 10:32:28 -0500
committerJason Wessel <jason.wessel@windriver.com>2013-03-02 09:52:18 -0500
commit4eb7a66d9410927fb8fbafad8b8298b627cdd128 (patch)
treec16c9844a02ac61b1d4aac613f18f3157620de46 /kernel/debug/kdb/kdb_main.c
parent3b0eb71ec9e22c6735c84f800d6523c96839efe6 (diff)
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/kdb/kdb_main.c')
-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)
683 return KDB_ARGCOUNT; 683 return KDB_ARGCOUNT;
684 defcmd_set = kmalloc((defcmd_set_count + 1) * sizeof(*defcmd_set), 684 defcmd_set = kmalloc((defcmd_set_count + 1) * sizeof(*defcmd_set),
685 GFP_KDB); 685 GFP_KDB);
686 if (!defcmd_set) { 686 if (!defcmd_set)
687 kdb_printf("Could not allocate new defcmd_set entry for %s\n", 687 goto fail_defcmd;
688 argv[1]);
689 defcmd_set = save_defcmd_set;
690 return KDB_NOTIMP;
691 }
692 memcpy(defcmd_set, save_defcmd_set, 688 memcpy(defcmd_set, save_defcmd_set,
693 defcmd_set_count * sizeof(*defcmd_set)); 689 defcmd_set_count * sizeof(*defcmd_set));
694 kfree(save_defcmd_set);
695 s = defcmd_set + defcmd_set_count; 690 s = defcmd_set + defcmd_set_count;
696 memset(s, 0, sizeof(*s)); 691 memset(s, 0, sizeof(*s));
697 s->usable = 1; 692 s->usable = 1;
698 s->name = kdb_strdup(argv[1], GFP_KDB); 693 s->name = kdb_strdup(argv[1], GFP_KDB);
694 if (!s->name)
695 goto fail_name;
699 s->usage = kdb_strdup(argv[2], GFP_KDB); 696 s->usage = kdb_strdup(argv[2], GFP_KDB);
697 if (!s->usage)
698 goto fail_usage;
700 s->help = kdb_strdup(argv[3], GFP_KDB); 699 s->help = kdb_strdup(argv[3], GFP_KDB);
700 if (!s->help)
701 goto fail_help;
701 if (s->usage[0] == '"') { 702 if (s->usage[0] == '"') {
702 strcpy(s->usage, s->usage+1); 703 strcpy(s->usage, argv[2]+1);
703 s->usage[strlen(s->usage)-1] = '\0'; 704 s->usage[strlen(s->usage)-1] = '\0';
704 } 705 }
705 if (s->help[0] == '"') { 706 if (s->help[0] == '"') {
706 strcpy(s->help, s->help+1); 707 strcpy(s->help, argv[3]+1);
707 s->help[strlen(s->help)-1] = '\0'; 708 s->help[strlen(s->help)-1] = '\0';
708 } 709 }
709 ++defcmd_set_count; 710 ++defcmd_set_count;
710 defcmd_in_progress = 1; 711 defcmd_in_progress = 1;
712 kfree(save_defcmd_set);
711 return 0; 713 return 0;
714fail_help:
715 kfree(s->usage);
716fail_usage:
717 kfree(s->name);
718fail_name:
719 kfree(defcmd_set);
720fail_defcmd:
721 kdb_printf("Could not allocate new defcmd_set entry for %s\n", argv[1]);
722 defcmd_set = save_defcmd_set;
723 return KDB_NOTIMP;
712} 724}
713 725
714/* 726/*