From 3602ad8f6ebb786adf1e09b4f39e9e9465d2fffc Mon Sep 17 00:00:00 2001 From: John Levon Date: Wed, 24 Nov 2021 23:15:33 +0000 Subject: 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 Reviewed-by: Swapnil Ingle Reviewed-by: Thanos Makatos --- lib/common.h | 8 ++++++++ lib/libvfio-user.c | 3 +-- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'lib') 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); -- cgit v1.1