mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
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: dc7d552705 ("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>
This commit is contained in:
parent
1865f1ea3b
commit
ac0159129e
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user