Skip to content

Commit 4eb7a66

Browse files
committed
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>
1 parent 3b0eb71 commit 4eb7a66

1 file changed

Lines changed: 21 additions & 9 deletions

File tree

kernel/debug/kdb/kdb_main.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -683,32 +683,44 @@ static int kdb_defcmd(int argc, const char **argv)
683683
return KDB_ARGCOUNT;
684684
defcmd_set = kmalloc((defcmd_set_count + 1) * sizeof(*defcmd_set),
685685
GFP_KDB);
686-
if (!defcmd_set) {
687-
kdb_printf("Could not allocate new defcmd_set entry for %s\n",
688-
argv[1]);
689-
defcmd_set = save_defcmd_set;
690-
return KDB_NOTIMP;
691-
}
686+
if (!defcmd_set)
687+
goto fail_defcmd;
692688
memcpy(defcmd_set, save_defcmd_set,
693689
defcmd_set_count * sizeof(*defcmd_set));
694-
kfree(save_defcmd_set);
695690
s = defcmd_set + defcmd_set_count;
696691
memset(s, 0, sizeof(*s));
697692
s->usable = 1;
698693
s->name = kdb_strdup(argv[1], GFP_KDB);
694+
if (!s->name)
695+
goto fail_name;
699696
s->usage = kdb_strdup(argv[2], GFP_KDB);
697+
if (!s->usage)
698+
goto fail_usage;
700699
s->help = kdb_strdup(argv[3], GFP_KDB);
700+
if (!s->help)
701+
goto fail_help;
701702
if (s->usage[0] == '"') {
702-
strcpy(s->usage, s->usage+1);
703+
strcpy(s->usage, argv[2]+1);
703704
s->usage[strlen(s->usage)-1] = '\0';
704705
}
705706
if (s->help[0] == '"') {
706-
strcpy(s->help, s->help+1);
707+
strcpy(s->help, argv[3]+1);
707708
s->help[strlen(s->help)-1] = '\0';
708709
}
709710
++defcmd_set_count;
710711
defcmd_in_progress = 1;
712+
kfree(save_defcmd_set);
711713
return 0;
714+
fail_help:
715+
kfree(s->usage);
716+
fail_usage:
717+
kfree(s->name);
718+
fail_name:
719+
kfree(defcmd_set);
720+
fail_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;
712724
}
713725

714726
/*

0 commit comments

Comments
 (0)