aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJohn Levon <john.levon@nutanix.com>2021-11-24 23:45:27 +0000
committerGitHub <noreply@github.com>2021-11-24 23:45:27 +0000
commitd8a08f1a18370bcad4fa99a16bdbfc63dbbd35ad (patch)
tree6b3233f9b45e2b3a18c40d577a516dacd7c13ad0 /lib
parent75a0ac2c52402ff1d42bc9ff77e65832a463590d (diff)
downloadlibvfio-user-d8a08f1a18370bcad4fa99a16bdbfc63dbbd35ad.zip
libvfio-user-d8a08f1a18370bcad4fa99a16bdbfc63dbbd35ad.tar.gz
libvfio-user-d8a08f1a18370bcad4fa99a16bdbfc63dbbd35ad.tar.bz2
check ->argsz for VFIO_USER_DIRTY_PAGES (#628)
We weren't checking for a too-large ->argsz for this command. Signed-off-by: John Levon <john.levon@nutanix.com> Reviewed-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/libvfio-user.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c
index b922c2e..b2ffac6 100644
--- a/lib/libvfio-user.c
+++ b/lib/libvfio-user.c
@@ -893,8 +893,9 @@ handle_dirty_pages_get(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg)
dirty_pages_in = msg->in_data;
- if (msg->in_size < sizeof(*dirty_pages_in) + sizeof(*range_in)
- || dirty_pages_in->argsz < sizeof(*dirty_pages_out)) {
+ if (msg->in_size < sizeof(*dirty_pages_in) + sizeof(*range_in) ||
+ dirty_pages_in->argsz > SERVER_MAX_DATA_XFER_SIZE ||
+ dirty_pages_in->argsz < sizeof(*dirty_pages_out)) {
vfu_log(vfu_ctx, LOG_ERR, "invalid message size=%zu argsz=%u",
msg->in_size, dirty_pages_in->argsz);
return ERROR_INT(EINVAL);
@@ -902,9 +903,15 @@ handle_dirty_pages_get(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg)
range_in = msg->in_data + sizeof(*dirty_pages_in);
- /* NB: this is bound by MAX_DMA_SIZE. */
- argsz = sizeof(*dirty_pages_out) + sizeof(*range_out) +
- range_in->bitmap.size;
+ /*
+ * range_in is client-controlled, but we only need to protect against
+ * overflow here: we'll take MIN() against a validated value next, and
+ * dma_controller_dirty_page_get() will validate the actual ->bitmap.size
+ * value later, anyway.
+ */
+ argsz = satadd_u64(sizeof(*dirty_pages_out) + sizeof(*range_out),
+ range_in->bitmap.size);
+
msg->out_size = MIN(dirty_pages_in->argsz, argsz);
msg->out_data = malloc(msg->out_size);
if (msg->out_data == NULL) {