aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/common.h8
-rw-r--r--lib/irq.c14
2 files changed, 19 insertions, 3 deletions
diff --git a/lib/common.h b/lib/common.h
index 40b9b27..c4de49a 100644
--- a/lib/common.h
+++ b/lib/common.h
@@ -77,6 +77,14 @@ ERROR_PTR(int err)
return NULL;
}
+/* Saturating uint32_t addition. */
+static inline uint32_t
+satadd_u32(uint32_t a, uint32_t b)
+{
+ uint64_t res = a + b;
+ return (res < a) ? UINT32_MAX : res;
+}
+
/* Saturating uint64_t addition. */
static inline uint64_t
satadd_u64(uint64_t a, uint64_t b)
diff --git a/lib/irq.c b/lib/irq.c
index 183d071..a6fd575 100644
--- a/lib/irq.c
+++ b/lib/irq.c
@@ -312,12 +312,20 @@ device_set_irqs_validate(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg)
line = __LINE__;
goto invalid;
}
- // Ensure irq_set's start and count are within bounds.
- if ((irq_set->start >= vfu_ctx->irq_count[irq_set->index]) ||
- (irq_set->start + irq_set->count > vfu_ctx->irq_count[irq_set->index])) {
+
+ // Ensure irq_set's start is within bounds.
+ if (irq_set->start >= vfu_ctx->irq_count[irq_set->index]) {
+ line = __LINE__;
+ goto invalid;
+ }
+
+ // Ensure irq_set's start+count is within bounds.
+ if (satadd_u32(irq_set->start, irq_set->count) >
+ vfu_ctx->irq_count[irq_set->index]) {
line = __LINE__;
goto invalid;
}
+
// Only TRIGGER is valid for ERR/REQ.
if (((irq_set->index == VFIO_PCI_ERR_IRQ_INDEX) ||
(irq_set->index == VFIO_PCI_REQ_IRQ_INDEX)) &&