migration: reject out-of-range migration state boundary (#875)
Reject device_state == VFIO_USER_DEVICE_NUM_STATES to prevent
out-of-bounds access to the migration state transition table.
Also add a regression test for the boundary case.
Signed-off-by: Siddharth C <siddharthcibi@icloud.com>
Reviewed-by: Thanos Makatos <thanos.makatos@nutanix.com>
diff --git a/lib/migration.c b/lib/migration.c
index 02c29c1..f995fca 100644
--- a/lib/migration.c
+++ b/lib/migration.c
@@ -268,7 +268,7 @@
uint32_t state;
ssize_t ret = 0;
- if (device_state > VFIO_USER_DEVICE_NUM_STATES) {
+ if (device_state >= VFIO_USER_DEVICE_NUM_STATES) {
return ERROR_INT(EINVAL);
}
diff --git a/test/py/libvfio_user.py b/test/py/libvfio_user.py
index 92188b0..7bddb3d 100644
--- a/test/py/libvfio_user.py
+++ b/test/py/libvfio_user.py
@@ -237,6 +237,7 @@
VFIO_USER_DEVICE_STATE_RUNNING_P2P = 5
VFIO_USER_DEVICE_STATE_PRE_COPY = 6
VFIO_USER_DEVICE_STATE_PRE_COPY_P2P = 7
+VFIO_USER_DEVICE_NUM_STATES = 8
VFIO_DEVICE_FEATURE_MASK = 0xffff
VFIO_DEVICE_FEATURE_GET = (1 << 16)
diff --git a/test/py/test_migration.py b/test/py/test_migration.py
index d423119..3fc3d19 100644
--- a/test/py/test_migration.py
+++ b/test/py/test_migration.py
@@ -322,6 +322,11 @@
transition_to_migr_state(0xabcd, expect=errno.EINVAL)
+def test_migration_num_states_boundary():
+ transition_to_migr_state(VFIO_USER_DEVICE_NUM_STATES,
+ expect=errno.EINVAL)
+
+
def test_migration_failed_callback():
setup_fail_callbacks(0xbeef)
transition_to_migr_state(VFIO_USER_DEVICE_STATE_RUNNING, expect=0xbeef)