aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJohn Levon <john.levon@nutanix.com>2021-11-24 23:15:33 +0000
committerGitHub <noreply@github.com>2021-11-24 23:15:33 +0000
commit3602ad8f6ebb786adf1e09b4f39e9e9465d2fffc (patch)
treeb38ba6db720a48965dde06872277d175fc8379d6 /lib
parentace83abb5d62ef91bafd20219be1bdaf4f57f091 (diff)
downloadlibvfio-user-3602ad8f6ebb786adf1e09b4f39e9e9465d2fffc.zip
libvfio-user-3602ad8f6ebb786adf1e09b4f39e9e9465d2fffc.tar.gz
libvfio-user-3602ad8f6ebb786adf1e09b4f39e9e9465d2fffc.tar.bz2
is_valid_region_access(): account for wrap-around (#624)
AFL++ found this, though we already knew about it, so fix it by comparing against a saturating addition. This was the only instance of client-controlled potential overflow I noticed. Signed-off-by: John Levon <john.levon@nutanix.com> Reviewed-by: Swapnil Ingle <swapnil.ingle@nutanix.com> Reviewed-by: Thanos Makatos <thanos.makatos@nutanix.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/common.h8
-rw-r--r--lib/libvfio-user.c3
2 files changed, 9 insertions, 2 deletions
diff --git a/lib/common.h b/lib/common.h
index 599759f..4d60199 100644
--- a/lib/common.h
+++ b/lib/common.h
@@ -58,6 +58,14 @@
#define ROUND_DOWN(x, a) ((x) & ~((a)-1))
#define ROUND_UP(x,a) ROUND_DOWN((x)+(a)-1, a)
+/* Saturating uint64_t addition. */
+static inline uint64_t
+satadd_u64(uint64_t a, uint64_t b)
+{
+ uint64_t res = a + b;
+ return (res < a) ? UINT64_MAX : res;
+}
+
/*
* The size, in bytes, of the bitmap that represents the given range with the
* given page size.
diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c
index 94a3419..9014c40 100644
--- a/lib/libvfio-user.c
+++ b/lib/libvfio-user.c
@@ -275,8 +275,7 @@ is_valid_region_access(vfu_ctx_t *vfu_ctx, size_t size, uint16_t cmd,
return false;
}
- // FIXME: need to audit later for wraparound
- if (ra->offset + ra->count > vfu_ctx->reg_info[index].size) {
+ if (satadd_u64(ra->offset, ra->count) > vfu_ctx->reg_info[index].size) {
vfu_log(vfu_ctx, LOG_ERR, "out of bounds region access %#lx-%#lx "
"(size %u)", ra->offset, ra->offset + ra->count,
vfu_ctx->reg_info[index].size);