devaddr is used in 1 << d->devaddr bit shifts in do_adb_request() and adb_poll(). A crafted migration stream could set it to a value outside [0, MAX_ADB_DEVICES), causing undefined behavior.
Add a post_load validator to reject out-of-range values. Reported-by: Pavee Hui <[email protected]> Fixes: 0606b2883038 ("adb: introduce realize/unrealize and VMStateDescription for ADB bus") Signed-off-by: Marc-André Lureau <[email protected]> --- hw/input/adb.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hw/input/adb.c b/hw/input/adb.c index 7c67d2baa663..b6319fa31535 100644 --- a/hw/input/adb.c +++ b/hw/input/adb.c @@ -280,10 +280,21 @@ static const TypeInfo adb_bus_type_info = { .class_init = adb_bus_class_init, }; +static int adb_device_post_load(void *opaque, int version_id) +{ + ADBDevice *d = opaque; + + if (d->devaddr < 0 || d->devaddr >= MAX_ADB_DEVICES) { + return -EINVAL; + } + return 0; +} + const VMStateDescription vmstate_adb_device = { .name = "adb_device", .version_id = 0, .minimum_version_id = 0, + .post_load = adb_device_post_load, .fields = (const VMStateField[]) { VMSTATE_INT32(devaddr, ADBDevice), VMSTATE_INT32(handler, ADBDevice), -- 2.56.0.rc0.29.g47ce80527c56
