|
45 | 45 | #include <linux/proc_fs.h>
|
46 | 46 | #include <linux/uaccess.h>
|
47 | 47 | #include <linux/slab.h>
|
| 48 | +#include <linux/security.h> |
48 | 49 | #include "kdb_private.h"
|
49 | 50 |
|
50 | 51 | #undef MODULE_PARAM_PREFIX
|
@@ -166,10 +167,62 @@ struct task_struct *kdb_curr_task(int cpu)
|
166 | 167 | }
|
167 | 168 |
|
168 | 169 | /*
|
169 |
| - * Check whether the flags of the current command and the permissions |
170 |
| - * of the kdb console has allow a command to be run. |
| 170 | + * Update the permissions flags (kdb_cmd_enabled) to match the |
| 171 | + * current lockdown state. |
| 172 | + * |
| 173 | + * Within this function the calls to security_locked_down() are "lazy". We |
| 174 | + * avoid calling them if the current value of kdb_cmd_enabled already excludes |
| 175 | + * flags that might be subject to lockdown. Additionally we deliberately check |
| 176 | + * the lockdown flags independently (even though read lockdown implies write |
| 177 | + * lockdown) since that results in both simpler code and clearer messages to |
| 178 | + * the user on first-time debugger entry. |
| 179 | + * |
| 180 | + * The permission masks during a read+write lockdown permits the following |
| 181 | + * flags: INSPECT, SIGNAL, REBOOT (and ALWAYS_SAFE). |
| 182 | + * |
| 183 | + * The INSPECT commands are not blocked during lockdown because they are |
| 184 | + * not arbitrary memory reads. INSPECT covers the backtrace family (sometimes |
| 185 | + * forcing them to have no arguments) and lsmod. These commands do expose |
| 186 | + * some kernel state but do not allow the developer seated at the console to |
| 187 | + * choose what state is reported. SIGNAL and REBOOT should not be controversial, |
| 188 | + * given these are allowed for root during lockdown already. |
| 189 | + */ |
| 190 | +static void kdb_check_for_lockdown(void) |
| 191 | +{ |
| 192 | + const int write_flags = KDB_ENABLE_MEM_WRITE | |
| 193 | + KDB_ENABLE_REG_WRITE | |
| 194 | + KDB_ENABLE_FLOW_CTRL; |
| 195 | + const int read_flags = KDB_ENABLE_MEM_READ | |
| 196 | + KDB_ENABLE_REG_READ; |
| 197 | + |
| 198 | + bool need_to_lockdown_write = false; |
| 199 | + bool need_to_lockdown_read = false; |
| 200 | + |
| 201 | + if (kdb_cmd_enabled & (KDB_ENABLE_ALL | write_flags)) |
| 202 | + need_to_lockdown_write = |
| 203 | + security_locked_down(LOCKDOWN_DBG_WRITE_KERNEL); |
| 204 | + |
| 205 | + if (kdb_cmd_enabled & (KDB_ENABLE_ALL | read_flags)) |
| 206 | + need_to_lockdown_read = |
| 207 | + security_locked_down(LOCKDOWN_DBG_READ_KERNEL); |
| 208 | + |
| 209 | + /* De-compose KDB_ENABLE_ALL if required */ |
| 210 | + if (need_to_lockdown_write || need_to_lockdown_read) |
| 211 | + if (kdb_cmd_enabled & KDB_ENABLE_ALL) |
| 212 | + kdb_cmd_enabled = KDB_ENABLE_MASK & ~KDB_ENABLE_ALL; |
| 213 | + |
| 214 | + if (need_to_lockdown_write) |
| 215 | + kdb_cmd_enabled &= ~write_flags; |
| 216 | + |
| 217 | + if (need_to_lockdown_read) |
| 218 | + kdb_cmd_enabled &= ~read_flags; |
| 219 | +} |
| 220 | + |
| 221 | +/* |
| 222 | + * Check whether the flags of the current command, the permissions of the kdb |
| 223 | + * console and the lockdown state allow a command to be run. |
171 | 224 | */
|
172 |
| -static inline bool kdb_check_flags(kdb_cmdflags_t flags, int permissions, |
| 225 | +static bool kdb_check_flags(kdb_cmdflags_t flags, int permissions, |
173 | 226 | bool no_args)
|
174 | 227 | {
|
175 | 228 | /* permissions comes from userspace so needs massaging slightly */
|
@@ -1180,6 +1233,9 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs,
|
1180 | 1233 | kdb_curr_task(raw_smp_processor_id());
|
1181 | 1234 |
|
1182 | 1235 | KDB_DEBUG_STATE("kdb_local 1", reason);
|
| 1236 | + |
| 1237 | + kdb_check_for_lockdown(); |
| 1238 | + |
1183 | 1239 | kdb_go_count = 0;
|
1184 | 1240 | if (reason == KDB_REASON_DEBUG) {
|
1185 | 1241 | /* special case below */
|
|
0 commit comments