Skip to content

Commit 3e82e39

Browse files
committed
kdb: Categorize kdb commands (similar to SysRq categorization)
jira VULN-1501 cve-pre CVE-2022-21499 commit-author Daniel Thompson <daniel.thompson@linaro.org> commit 9452e97 This patch introduces several new flags to collect kdb commands into groups (later allowing them to be optionally disabled). This follows similar prior art to enable/disable magic sysrq commands. The commands have been categorized as follows: Always on: go (w/o args), env, set, help, ?, cpu (w/o args), sr, dmesg, disable_nmi, defcmd, summary, grephelp Mem read: md, mdr, mdp, mds, ef, bt (with args), per_cpu Mem write: mm Reg read: rd Reg write: go (with args), rm Inspect: bt (w/o args), btp, bta, btc, btt, ps, pid, lsmod Flow ctrl: bp, bl, bph, bc, be, bd, ss Signal: kill Reboot: reboot All: cpu, kgdb, (and all of the above), nmi_console Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org> Cc: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Jason Wessel <jason.wessel@windriver.com> (cherry picked from commit 9452e97) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
1 parent 733517b commit 3e82e39

4 files changed

Lines changed: 148 additions & 43 deletions

File tree

include/linux/kdb.h

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,53 @@
1313
* Copyright (C) 2009 Jason Wessel <jason.wessel@windriver.com>
1414
*/
1515

16+
/* Shifted versions of the command enable bits are be used if the command
17+
* has no arguments (see kdb_check_flags). This allows commands, such as
18+
* go, to have different permissions depending upon whether it is called
19+
* with an argument.
20+
*/
21+
#define KDB_ENABLE_NO_ARGS_SHIFT 10
22+
1623
typedef enum {
17-
KDB_REPEAT_NO_ARGS = 0x1, /* Repeat the command w/o arguments */
18-
KDB_REPEAT_WITH_ARGS = 0x2, /* Repeat the command w/ its arguments */
24+
KDB_ENABLE_ALL = (1 << 0), /* Enable everything */
25+
KDB_ENABLE_MEM_READ = (1 << 1),
26+
KDB_ENABLE_MEM_WRITE = (1 << 2),
27+
KDB_ENABLE_REG_READ = (1 << 3),
28+
KDB_ENABLE_REG_WRITE = (1 << 4),
29+
KDB_ENABLE_INSPECT = (1 << 5),
30+
KDB_ENABLE_FLOW_CTRL = (1 << 6),
31+
KDB_ENABLE_SIGNAL = (1 << 7),
32+
KDB_ENABLE_REBOOT = (1 << 8),
33+
/* User exposed values stop here, all remaining flags are
34+
* exclusively used to describe a commands behaviour.
35+
*/
36+
37+
KDB_ENABLE_ALWAYS_SAFE = (1 << 9),
38+
KDB_ENABLE_MASK = (1 << KDB_ENABLE_NO_ARGS_SHIFT) - 1,
39+
40+
KDB_ENABLE_ALL_NO_ARGS = KDB_ENABLE_ALL << KDB_ENABLE_NO_ARGS_SHIFT,
41+
KDB_ENABLE_MEM_READ_NO_ARGS = KDB_ENABLE_MEM_READ
42+
<< KDB_ENABLE_NO_ARGS_SHIFT,
43+
KDB_ENABLE_MEM_WRITE_NO_ARGS = KDB_ENABLE_MEM_WRITE
44+
<< KDB_ENABLE_NO_ARGS_SHIFT,
45+
KDB_ENABLE_REG_READ_NO_ARGS = KDB_ENABLE_REG_READ
46+
<< KDB_ENABLE_NO_ARGS_SHIFT,
47+
KDB_ENABLE_REG_WRITE_NO_ARGS = KDB_ENABLE_REG_WRITE
48+
<< KDB_ENABLE_NO_ARGS_SHIFT,
49+
KDB_ENABLE_INSPECT_NO_ARGS = KDB_ENABLE_INSPECT
50+
<< KDB_ENABLE_NO_ARGS_SHIFT,
51+
KDB_ENABLE_FLOW_CTRL_NO_ARGS = KDB_ENABLE_FLOW_CTRL
52+
<< KDB_ENABLE_NO_ARGS_SHIFT,
53+
KDB_ENABLE_SIGNAL_NO_ARGS = KDB_ENABLE_SIGNAL
54+
<< KDB_ENABLE_NO_ARGS_SHIFT,
55+
KDB_ENABLE_REBOOT_NO_ARGS = KDB_ENABLE_REBOOT
56+
<< KDB_ENABLE_NO_ARGS_SHIFT,
57+
KDB_ENABLE_ALWAYS_SAFE_NO_ARGS = KDB_ENABLE_ALWAYS_SAFE
58+
<< KDB_ENABLE_NO_ARGS_SHIFT,
59+
KDB_ENABLE_MASK_NO_ARGS = KDB_ENABLE_MASK << KDB_ENABLE_NO_ARGS_SHIFT,
60+
61+
KDB_REPEAT_NO_ARGS = 0x40000000, /* Repeat the command w/o arguments */
62+
KDB_REPEAT_WITH_ARGS = 0x80000000, /* Repeat the command with args */
1963
} kdb_cmdflags_t;
2064

2165
typedef int (*kdb_func_t)(int, const char **);

kernel/debug/kdb/kdb_bp.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -532,21 +532,28 @@ void __init kdb_initbptab(void)
532532
bp->bp_free = 1;
533533

534534
kdb_register_flags("bp", kdb_bp, "[<vaddr>]",
535-
"Set/Display breakpoints", 0, KDB_REPEAT_NO_ARGS);
535+
"Set/Display breakpoints", 0,
536+
KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS);
536537
kdb_register_flags("bl", kdb_bp, "[<vaddr>]",
537-
"Display breakpoints", 0, KDB_REPEAT_NO_ARGS);
538+
"Display breakpoints", 0,
539+
KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS);
538540
if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT)
539541
kdb_register_flags("bph", kdb_bp, "[<vaddr>]",
540-
"[datar [length]|dataw [length]] Set hw brk", 0, KDB_REPEAT_NO_ARGS);
542+
"[datar [length]|dataw [length]] Set hw brk", 0,
543+
KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS);
541544
kdb_register_flags("bc", kdb_bc, "<bpnum>",
542-
"Clear Breakpoint", 0, 0);
545+
"Clear Breakpoint", 0,
546+
KDB_ENABLE_FLOW_CTRL);
543547
kdb_register_flags("be", kdb_bc, "<bpnum>",
544-
"Enable Breakpoint", 0, 0);
548+
"Enable Breakpoint", 0,
549+
KDB_ENABLE_FLOW_CTRL);
545550
kdb_register_flags("bd", kdb_bc, "<bpnum>",
546-
"Disable Breakpoint", 0, 0);
551+
"Disable Breakpoint", 0,
552+
KDB_ENABLE_FLOW_CTRL);
547553

548554
kdb_register_flags("ss", kdb_ss, "",
549-
"Single Step", 1, KDB_REPEAT_NO_ARGS);
555+
"Single Step", 1,
556+
KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS);
550557
/*
551558
* Architecture dependent initialization.
552559
*/

kernel/debug/kdb/kdb_main.c

Lines changed: 87 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,26 @@ struct task_struct *kdb_curr_task(int cpu)
187187
return p;
188188
}
189189

190+
/*
191+
* Check whether the flags of the current command and the permissions
192+
* of the kdb console has allow a command to be run.
193+
*/
194+
static inline bool kdb_check_flags(kdb_cmdflags_t flags, int permissions,
195+
bool no_args)
196+
{
197+
/* permissions comes from userspace so needs massaging slightly */
198+
permissions &= KDB_ENABLE_MASK;
199+
permissions |= KDB_ENABLE_ALWAYS_SAFE;
200+
201+
/* some commands change group when launched with no arguments */
202+
if (no_args)
203+
permissions |= permissions << KDB_ENABLE_NO_ARGS_SHIFT;
204+
205+
flags |= KDB_ENABLE_ALL;
206+
207+
return permissions & flags;
208+
}
209+
190210
/*
191211
* kdbgetenv - This function will return the character string value of
192212
* an environment variable.
@@ -641,8 +661,13 @@ static int kdb_defcmd2(const char *cmdstr, const char *argv0)
641661
if (!s->count)
642662
s->usable = 0;
643663
if (s->usable)
644-
kdb_register(s->name, kdb_exec_defcmd,
645-
s->usage, s->help, 0);
664+
/* macros are always safe because when executed each
665+
* internal command re-enters kdb_parse() and is
666+
* safety checked individually.
667+
*/
668+
kdb_register_flags(s->name, kdb_exec_defcmd, s->usage,
669+
s->help, 0,
670+
KDB_ENABLE_ALWAYS_SAFE);
646671
return 0;
647672
}
648673
if (!s->usable)
@@ -2757,78 +2782,107 @@ static void __init kdb_inittab(void)
27572782

27582783
kdb_register_flags("md", kdb_md, "<vaddr>",
27592784
"Display Memory Contents, also mdWcN, e.g. md8c1", 1,
2760-
KDB_REPEAT_NO_ARGS);
2785+
KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS);
27612786
kdb_register_flags("mdr", kdb_md, "<vaddr> <bytes>",
2762-
"Display Raw Memory", 0, KDB_REPEAT_NO_ARGS);
2787+
"Display Raw Memory", 0,
2788+
KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS);
27632789
kdb_register_flags("mdp", kdb_md, "<paddr> <bytes>",
2764-
"Display Physical Memory", 0, KDB_REPEAT_NO_ARGS);
2790+
"Display Physical Memory", 0,
2791+
KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS);
27652792
kdb_register_flags("mds", kdb_md, "<vaddr>",
2766-
"Display Memory Symbolically", 0, KDB_REPEAT_NO_ARGS);
2793+
"Display Memory Symbolically", 0,
2794+
KDB_ENABLE_MEM_READ | KDB_REPEAT_NO_ARGS);
27672795
kdb_register_flags("mm", kdb_mm, "<vaddr> <contents>",
2768-
"Modify Memory Contents", 0, KDB_REPEAT_NO_ARGS);
2796+
"Modify Memory Contents", 0,
2797+
KDB_ENABLE_MEM_WRITE | KDB_REPEAT_NO_ARGS);
27692798
kdb_register_flags("go", kdb_go, "[<vaddr>]",
2770-
"Continue Execution", 1, 0);
2799+
"Continue Execution", 1,
2800+
KDB_ENABLE_REG_WRITE | KDB_ENABLE_ALWAYS_SAFE_NO_ARGS);
27712801
kdb_register_flags("rd", kdb_rd, "",
2772-
"Display Registers", 0, 0);
2802+
"Display Registers", 0,
2803+
KDB_ENABLE_REG_READ);
27732804
kdb_register_flags("rm", kdb_rm, "<reg> <contents>",
2774-
"Modify Registers", 0, 0);
2805+
"Modify Registers", 0,
2806+
KDB_ENABLE_REG_WRITE);
27752807
kdb_register_flags("ef", kdb_ef, "<vaddr>",
2776-
"Display exception frame", 0, 0);
2808+
"Display exception frame", 0,
2809+
KDB_ENABLE_MEM_READ);
27772810
kdb_register_flags("bt", kdb_bt, "[<vaddr>]",
2778-
"Stack traceback", 1, 0);
2811+
"Stack traceback", 1,
2812+
KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS);
27792813
kdb_register_flags("btp", kdb_bt, "<pid>",
2780-
"Display stack for process <pid>", 0, 0);
2814+
"Display stack for process <pid>", 0,
2815+
KDB_ENABLE_INSPECT);
27812816
kdb_register_flags("bta", kdb_bt, "[D|R|S|T|C|Z|E|U|I|M|A]",
2782-
"Backtrace all processes matching state flag", 0, 0);
2817+
"Backtrace all processes matching state flag", 0,
2818+
KDB_ENABLE_INSPECT);
27832819
kdb_register_flags("btc", kdb_bt, "",
2784-
"Backtrace current process on each cpu", 0, 0);
2820+
"Backtrace current process on each cpu", 0,
2821+
KDB_ENABLE_INSPECT);
27852822
kdb_register_flags("btt", kdb_bt, "<vaddr>",
27862823
"Backtrace process given its struct task address", 0,
2787-
0);
2824+
KDB_ENABLE_MEM_READ | KDB_ENABLE_INSPECT_NO_ARGS);
27882825
kdb_register_flags("env", kdb_env, "",
2789-
"Show environment variables", 0, 0);
2826+
"Show environment variables", 0,
2827+
KDB_ENABLE_ALWAYS_SAFE);
27902828
kdb_register_flags("set", kdb_set, "",
2791-
"Set environment variables", 0, 0);
2829+
"Set environment variables", 0,
2830+
KDB_ENABLE_ALWAYS_SAFE);
27922831
kdb_register_flags("help", kdb_help, "",
2793-
"Display Help Message", 1, 0);
2832+
"Display Help Message", 1,
2833+
KDB_ENABLE_ALWAYS_SAFE);
27942834
kdb_register_flags("?", kdb_help, "",
2795-
"Display Help Message", 0, 0);
2835+
"Display Help Message", 0,
2836+
KDB_ENABLE_ALWAYS_SAFE);
27962837
kdb_register_flags("cpu", kdb_cpu, "<cpunum>",
2797-
"Switch to new cpu", 0, 0);
2838+
"Switch to new cpu", 0,
2839+
KDB_ENABLE_ALWAYS_SAFE_NO_ARGS);
27982840
kdb_register_flags("kgdb", kdb_kgdb, "",
27992841
"Enter kgdb mode", 0, 0);
28002842
kdb_register_flags("ps", kdb_ps, "[<flags>|A]",
2801-
"Display active task list", 0, 0);
2843+
"Display active task list", 0,
2844+
KDB_ENABLE_INSPECT);
28022845
kdb_register_flags("pid", kdb_pid, "<pidnum>",
2803-
"Switch to another task", 0, 0);
2846+
"Switch to another task", 0,
2847+
KDB_ENABLE_INSPECT);
28042848
kdb_register_flags("reboot", kdb_reboot, "",
2805-
"Reboot the machine immediately", 0, 0);
2849+
"Reboot the machine immediately", 0,
2850+
KDB_ENABLE_REBOOT);
28062851
#if defined(CONFIG_MODULES)
28072852
kdb_register_flags("lsmod", kdb_lsmod, "",
2808-
"List loaded kernel modules", 0, 0);
2853+
"List loaded kernel modules", 0,
2854+
KDB_ENABLE_INSPECT);
28092855
#endif
28102856
#if defined(CONFIG_MAGIC_SYSRQ)
28112857
kdb_register_flags("sr", kdb_sr, "<key>",
2812-
"Magic SysRq key", 0, 0);
2858+
"Magic SysRq key", 0,
2859+
KDB_ENABLE_ALWAYS_SAFE);
28132860
#endif
28142861
#if defined(CONFIG_PRINTK)
28152862
kdb_register_flags("dmesg", kdb_dmesg, "[lines]",
2816-
"Display syslog buffer", 0, 0);
2863+
"Display syslog buffer", 0,
2864+
KDB_ENABLE_ALWAYS_SAFE);
28172865
#endif
28182866
if (arch_kgdb_ops.enable_nmi) {
28192867
kdb_register_flags("disable_nmi", kdb_disable_nmi, "",
2820-
"Disable NMI entry to KDB", 0, 0);
2868+
"Disable NMI entry to KDB", 0,
2869+
KDB_ENABLE_ALWAYS_SAFE);
28212870
}
28222871
kdb_register_flags("defcmd", kdb_defcmd, "name \"usage\" \"help\"",
2823-
"Define a set of commands, down to endefcmd", 0, 0);
2872+
"Define a set of commands, down to endefcmd", 0,
2873+
KDB_ENABLE_ALWAYS_SAFE);
28242874
kdb_register_flags("kill", kdb_kill, "<-signal> <pid>",
2825-
"Send a signal to a process", 0, 0);
2875+
"Send a signal to a process", 0,
2876+
KDB_ENABLE_SIGNAL);
28262877
kdb_register_flags("summary", kdb_summary, "",
2827-
"Summarize the system", 4, 0);
2878+
"Summarize the system", 4,
2879+
KDB_ENABLE_ALWAYS_SAFE);
28282880
kdb_register_flags("per_cpu", kdb_per_cpu, "<sym> [<bytes>] [<cpu>]",
2829-
"Display per_cpu variables", 3, 0);
2881+
"Display per_cpu variables", 3,
2882+
KDB_ENABLE_MEM_READ);
28302883
kdb_register_flags("grephelp", kdb_grep_help, "",
2831-
"Display help on | grep", 0, 0);
2884+
"Display help on | grep", 0,
2885+
KDB_ENABLE_ALWAYS_SAFE);
28322886
}
28332887

28342888
/* Execute any commands defined in kdb_cmds. */

kernel/trace/trace_kdb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ static int kdb_ftdump(int argc, const char **argv)
128128
static __init int kdb_ftrace_register(void)
129129
{
130130
kdb_register_flags("ftdump", kdb_ftdump, "[skip_#lines] [cpu]",
131-
"Dump ftrace log", 0, 0);
131+
"Dump ftrace log", 0, KDB_ENABLE_ALWAYS_SAFE);
132132
return 0;
133133
}
134134

0 commit comments

Comments
 (0)