summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFang Xieyan <fangxy@xiaopeng.com>2026-09-15 02:03:44 +0800
committerDaniel Thompson <daniel@riscstar.com>2026-10-28 16:55:40 +0000
commitac0159129e2cb99a70c4b80cfbf58d03e092dc7b (patch)
tree2dd0e001cce129578973f293340ea0383c596c7e
parent1865f1ea3b54bde68da5a68f0f56fbc1ebf69fbf (diff)
kgdb: Fix buffer overflow in the 'm' packet handler
gdb_cmd_memread() passes the length of the 'm' packet straight to kgdb_mem2hex(), which hex-encodes the reply into remcom_out_buffer[BUFMAX] without checking that the reply fits. A client on the KGDB I/O console can ask for a read of any size, and the hex encoding runs off the end of the buffer. kgdb_mem2hex() takes that length as an int count, so 2^31 truncates to a negative value and copy_from_kernel_nofault() is handed buf + count as its destination. On x86 BUFMAX is 1024, so a read of 512 bytes overruns by the single byte that terminates the hex string: BUG: KASAN: global-out-of-bounds in kgdb_mem2hex+0x1dd/0x230 Write of size 1 at addr ffffffff87651780 by task sh/1 ... The buggy address belongs to the variable: remcom_out_buffer+0x400/0x420 Bounds check the length before the hex encoding: if (length > (BUFMAX - 1) / 2) { error_packet(remcom_out_buffer, -EINVAL); return; } gdbstub_msg_write() already bounds the count it hex-encodes against BUFMAX. Reads over the limit never returned valid data, so an error reply loses nothing. Fixes: dc7d55270521 ("kgdb: core") Cc: stable@vger.kernel.org Assisted-by: Hawkeye:GLM-5.3-flash Assisted-by: Qoder:Qwen3.8-Max Signed-off-by: Fang Xieyan <fangxy@xiaopeng.com> Reviewed-by: Douglas Anderson <dianders@chromium.org> Link: https://lore.kernel.org/r/20260914180344.15485-1-fangxy@xiaopeng.com Signed-off-by: Daniel Thompson <daniel@riscstar.com>
-rw-r--r--kernel/debug/gdbstub.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/kernel/debug/gdbstub.c b/kernel/debug/gdbstub.c
index e271a436d60e..5774292c93ae 100644
--- a/kernel/debug/gdbstub.c
+++ b/kernel/debug/gdbstub.c
@@ -563,6 +563,14 @@ static void gdb_cmd_memread(struct kgdb_state *ks)
if (kgdb_hex2long(&ptr, &addr) > 0 && *ptr++ == ',' &&
kgdb_hex2long(&ptr, &length) > 0) {
+ /*
+ * The hex-encoded reply needs 2 * length + 1 bytes
+ * in remcom_out_buffer[BUFMAX].
+ */
+ if (length > (BUFMAX - 1) / 2) {
+ error_packet(remcom_out_buffer, -EINVAL);
+ return;
+ }
err = kgdb_mem2hex((char *)addr, remcom_out_buffer, length);
if (!err)
error_packet(remcom_out_buffer, -EINVAL);