A malicious or corrupted migration stream can supply out-of-range
rptr, wptr, or count values for the keyboard ring buffer, leading
to out-of-bounds accesses after load.

Add a post_load handler that rejects values outside the valid
range of the data buffer.

Fixes: 77cb0f5aafc8 ("Split adb.c into adb.c, adb-mouse.c and adb-kbd.c")
Reported-by: Pavee Hui <[email protected]>
Signed-off-by: Marc-André Lureau <[email protected]>
---
 hw/input/adb-kbd.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/hw/input/adb-kbd.c b/hw/input/adb-kbd.c
index 9d80a3849b77..8635354f024c 100644
--- a/hw/input/adb-kbd.c
+++ b/hw/input/adb-kbd.c
@@ -334,10 +334,23 @@ static void adb_keyboard_event(DeviceState *dev, 
QemuConsole *src,
     adb_kbd_put_keycode(s, keycode);
 }
 
+static int adb_kbd_post_load(void *opaque, int version_id)
+{
+    KBDState *s = opaque;
+
+    if (s->rptr < 0 || s->rptr >= sizeof(s->data) ||
+        s->wptr < 0 || s->wptr >= sizeof(s->data) ||
+        s->count < 0 || s->count > sizeof(s->data)) {
+        return -EINVAL;
+    }
+    return 0;
+}
+
 static const VMStateDescription vmstate_adb_kbd = {
     .name = "adb_kbd",
     .version_id = 2,
     .minimum_version_id = 2,
+    .post_load = adb_kbd_post_load,
     .fields = (const VMStateField[]) {
         VMSTATE_STRUCT(parent_obj, KBDState, 0, vmstate_adb_device, ADBDevice),
         VMSTATE_BUFFER(data, KBDState),

-- 
2.56.0.rc0.29.g47ce80527c56


Reply via email to