mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
HID: wacom: fix slab-out-of-bounds write in wacom_wac_queue_insert
wacom_wac_queue_insert() calls kfifo_skip() in a loop when the kfifo
doesn't have enough space for the incoming report. If the kfifo is
empty, kfifo_skip() reads stale data left in the kmalloc'd buffer
via __kfifo_peek_n() and interprets it as a record length, advancing
fifo->out by that garbage value. This corrupts the internal kfifo
state, causing kfifo_unused() to return a value much larger than the
actual buffer size, which bypasses __kfifo_in_r()'s guard:
if (len + recsize > kfifo_unused(fifo))
return 0;
kfifo_copy_in() then performs an out-of-bounds memcpy, writing up to
3842 bytes past the 256-byte buffer.
Add a !kfifo_is_empty() condition to the while loop so kfifo_skip()
is never called on an empty fifo, and check the return value of
kfifo_in() to reject reports that are too large for the fifo.
Suggested-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Fixes: 5e013ad206 ("HID: wacom: Remove static WACOM_PKGLEN_MAX limit")
Cc: stable@vger.kernel.org
Signed-off-by: Jinmo Yang <jinmo44.yang@gmail.com>
Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
This commit is contained in:
parent
e6f4f084ec
commit
6b3014ec0e
|
|
@ -54,7 +54,7 @@ static void wacom_wac_queue_insert(struct hid_device *hdev,
|
|||
{
|
||||
bool warned = false;
|
||||
|
||||
while (kfifo_avail(fifo) < size) {
|
||||
while (kfifo_avail(fifo) < size && !kfifo_is_empty(fifo)) {
|
||||
if (!warned)
|
||||
hid_warn(hdev, "%s: kfifo has filled, starting to drop events\n", __func__);
|
||||
warned = true;
|
||||
|
|
@ -62,7 +62,9 @@ static void wacom_wac_queue_insert(struct hid_device *hdev,
|
|||
kfifo_skip(fifo);
|
||||
}
|
||||
|
||||
kfifo_in(fifo, raw_data, size);
|
||||
if (!kfifo_in(fifo, raw_data, size))
|
||||
hid_warn_ratelimited(hdev, "%s: report is too large (%d)\n",
|
||||
__func__, size);
|
||||
}
|
||||
|
||||
static void wacom_wac_queue_flush(struct hid_device *hdev,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user