From ac0159129e2cb99a70c4b80cfbf58d03e092dc7b Mon Sep 17 00:00:00 2001 From: Fang Xieyan Date: Tue, 15 Sep 2026 02:03:44 +0800 Subject: 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 Reviewed-by: Douglas Anderson Link: https://lore.kernel.org/r/20260914180344.15485-1-fangxy@xiaopeng.com Signed-off-by: Daniel Thompson --- kernel/debug/gdbstub.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'kernel') 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); -- cgit v1.2.3