Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions kernel/debug/debug_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,29 @@ static int kgdb_cpu_enter(struct kgdb_state *ks, struct pt_regs *regs,
continue;
kgdb_connected = 0;
} else {
/*
* This is a brutal way to interfere with the debugger
* and prevent gdb being used to poke at kernel memory.
* This could cause trouble if lockdown is applied when
* there is already an active gdb session. For now the
* answer is simply "don't do that". Typically lockdown
* *will* be applied before the debug core gets started
* so only developers using kgdb for fairly advanced
* early kernel debug can be biten by this. Hopefully
* they are sophisticated enough to take care of
* themselves, especially with help from the lockdown
* message printed on the console!
*/
if (kernel_is_locked_down("Use of kgdb/kdb to write kernel RAM")) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first letter of this message isn't capitalized in the upstream commit. Change the message to "use of kgdb/kdb to write kernel RAM" to match upstream.

if (IS_ENABLED(CONFIG_KGDB_KDB)) {
/* Switch back to kdb if possible... */
dbg_kdb_mode = 1;
continue;
} else {
/* ... otherwise just bail */
break;
}
}
error = gdb_serial_stub(ks);
}

Expand Down
45 changes: 42 additions & 3 deletions kernel/debug/kdb/kdb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,46 @@ struct task_struct *kdb_curr_task(int cpu)
}

/*
* Check whether the flags of the current command and the permissions
* of the kdb console has allow a command to be run.
* Update the permissions flags (kdb_cmd_enabled) to match the
* current lockdown state.
*
* When the kernel is locked down, strip all memory/register read and
* write permissions as well as flow control from kdb_cmd_enabled.
*
* The remaining permitted flags are: INSPECT, SIGNAL, REBOOT
* (and ALWAYS_SAFE).
*
* INSPECT commands are not blocked during lockdown because they are
* not arbitrary memory reads. INSPECT covers the backtrace family
* (sometimes forcing them to have no arguments) and lsmod. These
* commands do expose some kernel state but do not allow the developer
* seated at the console to choose what state is reported. SIGNAL and
* REBOOT should not be controversial, given these are allowed for
* root during lockdown already.
Comment on lines +171 to +186
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment doesn't match the upstream commit (see interdiff output). Copy the function comment from the upstream commit wholesale.

*/
static void kdb_check_for_lockdown(void)
{
const int write_flags = KDB_ENABLE_MEM_WRITE |
KDB_ENABLE_REG_WRITE |
KDB_ENABLE_FLOW_CTRL;
const int read_flags = KDB_ENABLE_MEM_READ |
KDB_ENABLE_REG_READ;

if (!kernel_is_locked_down("Use of kgdb/kdb to read/write kernel RAM"))
return;

/* De-compose KDB_ENABLE_ALL if required */
if (kdb_cmd_enabled & KDB_ENABLE_ALL)
kdb_cmd_enabled = KDB_ENABLE_MASK & ~KDB_ENABLE_ALL;

kdb_cmd_enabled &= ~(write_flags | read_flags);
Comment on lines +196 to +203
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two subtle differences between this code and the upstream code:

  1. This will print a lockdown message even when kdb_cmd_enabled & KDB_ENABLE_ALL is false. The upstream commit only prints lockdown messages when it spots forbidden flags in kdb_cmd_enabled.
  2. The upstream commit provides two different lockdown messages in kdb_check_for_lockdown(): one for reads, one for writes.

Resolve both points by copying+pasting the entire kdb_check_for_lockdown() function from the upstream commit and then make the following two changes:

  1. Replace security_locked_down(LOCKDOWN_DBG_READ_KERNEL) with kernel_is_locked_down("use of kgdb/kdb to read kernel RAM")
  2. Replace security_locked_down(LOCKDOWN_DBG_WRITE_KERNEL) with kernel_is_locked_down("use of kgdb/kdb to write kernel RAM")

}

/*
* Check whether the flags of the current command, the permissions of the kdb
* console and the lockdown state allow a command to be run.
*/
static inline bool kdb_check_flags(kdb_cmdflags_t flags, int permissions,
static bool kdb_check_flags(kdb_cmdflags_t flags, int permissions,
bool no_args)
{
/* permissions comes from userspace so needs massaging slightly */
Expand Down Expand Up @@ -1169,6 +1205,9 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs,
kdb_curr_task(raw_smp_processor_id());

KDB_DEBUG_STATE("kdb_local 1", reason);

kdb_check_for_lockdown();

kdb_go_count = 0;
if (reason == KDB_REASON_DEBUG) {
/* special case below */
Expand Down
Loading