[ciqlts8_6] lockdown: also lock down previous kgdb use#895
[ciqlts8_6] lockdown: also lock down previous kgdb use#895ciq-kernel-automation[bot] wants to merge 1 commit intociqlts8_6from
Conversation
|
🤖 Validation Checks In Progress Workflow run: https://github.com/ctrliq/kernel-src-tree/actions/runs/22154387405 |
🔍 Upstream Linux Kernel Commit Check
This is an automated message from the kernel commit checker workflow. |
🔍 Interdiff Analysis
================================================================================
* DELTA DIFFERENCES - code changes that differ between the patches *
================================================================================
--- b/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -641,7 +641,7 @@
* 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")) {
+ if (security_locked_down(LOCKDOWN_DBG_WRITE_KERNEL)) {
if (IS_ENABLED(CONFIG_KGDB_KDB)) {
/* Switch back to kdb if possible... */
dbg_kdb_mode = 1;
--- b/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -171,19 +171,22 @@
* 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.
+ * Within this function the calls to security_locked_down() are "lazy". We
+ * avoid calling them if the current value of kdb_cmd_enabled already excludes
+ * flags that might be subject to lockdown. Additionally we deliberately check
+ * the lockdown flags independently (even though read lockdown implies write
+ * lockdown) since that results in both simpler code and clearer messages to
+ * the user on first-time debugger entry.
*
- * The remaining permitted flags are: INSPECT, SIGNAL, REBOOT
- * (and ALWAYS_SAFE).
+ * The permission masks during a read+write lockdown permits the following
+ * flags: 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.
+ * The 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.
*/
static void kdb_check_for_lockdown(void)
{
@@ -193,14 +196,27 @@
const int read_flags = KDB_ENABLE_MEM_READ |
KDB_ENABLE_REG_READ;
- if (!kernel_is_locked_down("kdb"))
- return;
+ bool need_to_lockdown_write = false;
+ bool need_to_lockdown_read = false;
+
+ if (kdb_cmd_enabled & (KDB_ENABLE_ALL | write_flags))
+ need_to_lockdown_write =
+ security_locked_down(LOCKDOWN_DBG_WRITE_KERNEL);
+
+ if (kdb_cmd_enabled & (KDB_ENABLE_ALL | read_flags))
+ need_to_lockdown_read =
+ security_locked_down(LOCKDOWN_DBG_READ_KERNEL);
/* De-compose KDB_ENABLE_ALL if required */
- if (kdb_cmd_enabled & KDB_ENABLE_ALL)
- kdb_cmd_enabled = KDB_ENABLE_MASK & ~KDB_ENABLE_ALL;
+ if (need_to_lockdown_write || need_to_lockdown_read)
+ if (kdb_cmd_enabled & KDB_ENABLE_ALL)
+ kdb_cmd_enabled = KDB_ENABLE_MASK & ~KDB_ENABLE_ALL;
+
+ if (need_to_lockdown_write)
+ kdb_cmd_enabled &= ~write_flags;
- kdb_cmd_enabled &= ~(write_flags | read_flags);
+ if (need_to_lockdown_read)
+ kdb_cmd_enabled &= ~read_flags;
}
/*
################################################################################
! REJECTED PATCH2 HUNKS - could not be compared; manual review needed !
################################################################################
--- b/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -53,6 +53,7 @@
#include <linux/vmacache.h>
#include <linux/rcupdate.h>
#include <linux/irq.h>
+#include <linux/security.h>
#include <asm/cacheflush.h>
#include <asm/byteorder.h>
--- b/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -45,6 +45,7 @@
#include <linux/proc_fs.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
+#include <linux/security.h>
#include "kdb_private.h"
#undef MODULE_PARAM_PREFIX
================================================================================
* ONLY IN PATCH2 - files not modified by patch1 *
================================================================================
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -121,10 +121,12 @@ enum lockdown_reason {
LOCKDOWN_DEBUGFS,
LOCKDOWN_XMON_WR,
LOCKDOWN_BPF_WRITE_USER,
+ LOCKDOWN_DBG_WRITE_KERNEL,
LOCKDOWN_INTEGRITY_MAX,
LOCKDOWN_KCORE,
LOCKDOWN_KPROBES,
LOCKDOWN_BPF_READ_KERNEL,
+ LOCKDOWN_DBG_READ_KERNEL,
LOCKDOWN_PERF,
LOCKDOWN_TRACEFS,
LOCKDOWN_XMON_RW,
--- a/security/security.c
+++ b/security/security.c
@@ -59,10 +59,12 @@ const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = {
[LOCKDOWN_DEBUGFS] = "debugfs access",
[LOCKDOWN_XMON_WR] = "xmon write access",
[LOCKDOWN_BPF_WRITE_USER] = "use of bpf to write user RAM",
+ [LOCKDOWN_DBG_WRITE_KERNEL] = "use of kgdb/kdb to write kernel RAM",
[LOCKDOWN_INTEGRITY_MAX] = "integrity",
[LOCKDOWN_KCORE] = "/proc/kcore access",
[LOCKDOWN_KPROBES] = "use of kprobes",
[LOCKDOWN_BPF_READ_KERNEL] = "use of bpf to read kernel RAM",
+ [LOCKDOWN_DBG_READ_KERNEL] = "use of kgdb/kdb to read kernel RAM",
[LOCKDOWN_PERF] = "unsafe use of perf",
[LOCKDOWN_TRACEFS] = "use of tracefs",
[LOCKDOWN_XMON_RW] = "xmon read and write access",This is an automated interdiff check for backported commits. |
|
✅ Validation checks completed successfully View full results: https://github.com/ctrliq/kernel-src-tree/actions/runs/22154387405 |
jira VULN-3157 cve CVE-2022-21499 commit-author Daniel Thompson <daniel.thompson@linaro.org> commit eadb2f4 upstream-diff: Adapted to use older kernel_is_locked_down() APIs as the Lockdown LSM changes introduced in 5.4 where not backported to this kernel. KGDB and KDB allow read and write access to kernel memory, and thus should be restricted during lockdown. An attacker with access to a serial port (for example, via a hypervisor console, which some cloud vendors provide over the network) could trigger the debugger so it is important that the debugger respect the lockdown mode when/if it is triggered. Fix this by integrating lockdown into kdb's existing permissions mechanism. Unfortunately kgdb does not have any permissions mechanism (although it certainly could be added later) so, for now, kgdb is simply and brutally disabled by immediately exiting the gdb stub without taking any action. For lockdowns established early in the boot (e.g. the normal case) then this should be fine but on systems where kgdb has set breakpoints before the lockdown is enacted than "bad things" will happen. CVE: CVE-2022-21499 Co-developed-by: Stephen Brennan <stephen.s.brennan@oracle.com> Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com> Reviewed-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> (cherry picked from commit eadb2f4) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
f06708d to
fdd34a2
Compare
|
🤖 Validation Checks In Progress Workflow run: https://github.com/ctrliq/kernel-src-tree/actions/runs/22156694181 |
🔍 Upstream Linux Kernel Commit Check
This is an automated message from the kernel commit checker workflow. |
🔍 Interdiff Analysis
================================================================================
* DELTA DIFFERENCES - code changes that differ between the patches *
================================================================================
--- b/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -641,7 +641,7 @@
* 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")) {
+ if (security_locked_down(LOCKDOWN_DBG_WRITE_KERNEL)) {
if (IS_ENABLED(CONFIG_KGDB_KDB)) {
/* Switch back to kdb if possible... */
dbg_kdb_mode = 1;
--- b/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -171,19 +171,22 @@
* 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.
+ * Within this function the calls to security_locked_down() are "lazy". We
+ * avoid calling them if the current value of kdb_cmd_enabled already excludes
+ * flags that might be subject to lockdown. Additionally we deliberately check
+ * the lockdown flags independently (even though read lockdown implies write
+ * lockdown) since that results in both simpler code and clearer messages to
+ * the user on first-time debugger entry.
*
- * The remaining permitted flags are: INSPECT, SIGNAL, REBOOT
- * (and ALWAYS_SAFE).
+ * The permission masks during a read+write lockdown permits the following
+ * flags: 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.
+ * The 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.
*/
static void kdb_check_for_lockdown(void)
{
@@ -193,14 +196,27 @@
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;
+ bool need_to_lockdown_write = false;
+ bool need_to_lockdown_read = false;
+
+ if (kdb_cmd_enabled & (KDB_ENABLE_ALL | write_flags))
+ need_to_lockdown_write =
+ security_locked_down(LOCKDOWN_DBG_WRITE_KERNEL);
+
+ if (kdb_cmd_enabled & (KDB_ENABLE_ALL | read_flags))
+ need_to_lockdown_read =
+ security_locked_down(LOCKDOWN_DBG_READ_KERNEL);
/* De-compose KDB_ENABLE_ALL if required */
- if (kdb_cmd_enabled & KDB_ENABLE_ALL)
- kdb_cmd_enabled = KDB_ENABLE_MASK & ~KDB_ENABLE_ALL;
+ if (need_to_lockdown_write || need_to_lockdown_read)
+ if (kdb_cmd_enabled & KDB_ENABLE_ALL)
+ kdb_cmd_enabled = KDB_ENABLE_MASK & ~KDB_ENABLE_ALL;
+
+ if (need_to_lockdown_write)
+ kdb_cmd_enabled &= ~write_flags;
- kdb_cmd_enabled &= ~(write_flags | read_flags);
+ if (need_to_lockdown_read)
+ kdb_cmd_enabled &= ~read_flags;
}
/*
################################################################################
! REJECTED PATCH2 HUNKS - could not be compared; manual review needed !
################################################################################
--- b/kernel/debug/debug_core.c
+++ b/kernel/debug/debug_core.c
@@ -53,6 +53,7 @@
#include <linux/vmacache.h>
#include <linux/rcupdate.h>
#include <linux/irq.h>
+#include <linux/security.h>
#include <asm/cacheflush.h>
#include <asm/byteorder.h>
--- b/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -45,6 +45,7 @@
#include <linux/proc_fs.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
+#include <linux/security.h>
#include "kdb_private.h"
#undef MODULE_PARAM_PREFIX
================================================================================
* ONLY IN PATCH2 - files not modified by patch1 *
================================================================================
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -121,10 +121,12 @@ enum lockdown_reason {
LOCKDOWN_DEBUGFS,
LOCKDOWN_XMON_WR,
LOCKDOWN_BPF_WRITE_USER,
+ LOCKDOWN_DBG_WRITE_KERNEL,
LOCKDOWN_INTEGRITY_MAX,
LOCKDOWN_KCORE,
LOCKDOWN_KPROBES,
LOCKDOWN_BPF_READ_KERNEL,
+ LOCKDOWN_DBG_READ_KERNEL,
LOCKDOWN_PERF,
LOCKDOWN_TRACEFS,
LOCKDOWN_XMON_RW,
--- a/security/security.c
+++ b/security/security.c
@@ -59,10 +59,12 @@ const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = {
[LOCKDOWN_DEBUGFS] = "debugfs access",
[LOCKDOWN_XMON_WR] = "xmon write access",
[LOCKDOWN_BPF_WRITE_USER] = "use of bpf to write user RAM",
+ [LOCKDOWN_DBG_WRITE_KERNEL] = "use of kgdb/kdb to write kernel RAM",
[LOCKDOWN_INTEGRITY_MAX] = "integrity",
[LOCKDOWN_KCORE] = "/proc/kcore access",
[LOCKDOWN_KPROBES] = "use of kprobes",
[LOCKDOWN_BPF_READ_KERNEL] = "use of bpf to read kernel RAM",
+ [LOCKDOWN_DBG_READ_KERNEL] = "use of kgdb/kdb to read kernel RAM",
[LOCKDOWN_PERF] = "unsafe use of perf",
[LOCKDOWN_TRACEFS] = "use of tracefs",
[LOCKDOWN_XMON_RW] = "xmon read and write access",This is an automated interdiff check for backported commits. |
|
✅ Validation checks completed successfully View full results: https://github.com/ctrliq/kernel-src-tree/actions/runs/22156694181 |
|
Looks right to me. Its interesting that only the writes are taken care of in rocky8_10: |
Yeah, being able to read seems like a security risk ... but I guess if you're in the kgdb you're already able to get most information :| I"m also happy to adapt this to the RHEL logic more closely (that may very well be whats in the EUS kernel but 🤷 since we don't have visibility into it) but we're already divergent from the RESF 1:1 bug compatibility anyways. |
| * 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. |
There was a problem hiding this comment.
This comment doesn't match the upstream commit (see interdiff output). Copy the function comment from the upstream commit wholesale.
| 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); |
There was a problem hiding this comment.
There are two subtle differences between this code and the upstream code:
- This will print a lockdown message even when
kdb_cmd_enabled & KDB_ENABLE_ALLis false. The upstream commit only prints lockdown messages when it spots forbidden flags in kdb_cmd_enabled. - 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:
- Replace
security_locked_down(LOCKDOWN_DBG_READ_KERNEL)withkernel_is_locked_down("use of kgdb/kdb to read kernel RAM") - Replace
security_locked_down(LOCKDOWN_DBG_WRITE_KERNEL)withkernel_is_locked_down("use of kgdb/kdb to write kernel RAM")
| * 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")) { |
There was a problem hiding this comment.
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.
Summary
This PR has been automatically created after successful completion of all CI stages.
Rocky8_10 reference
It was attempted to be back ported in this commit sha on rocky8 rebuilds however it did not cleanly apply 61b2455
The SPLAT commit that it was associated to is this one:
8fe840b
Red Hat did not backport the full LSM 5.4 patches but instead adapted their previous method (before the LSM unification) to kernel_is_locked_down(). A note, redhat did not, like the source commit drop the read access during the KDB console connect. They did prevent the write so they're maintaining the integrity of the kernel where as since we're dropping the read and write we're also making it a confidentiality mode". Other wise we chose to use their "Panic Messaging" as well.
Commit Message(s)
Test Results
✅ Build Stage
✅ Boot Verification
✅ Kernel Selftests
✅ Test Comparison
🤖 This PR was automatically generated by GitHub Actions
Run ID: 22156378471