From 6b610621336d7d75dd597ba1a4e05359be3ca909 Mon Sep 17 00:00:00 2001 From: Dan Cross Date: Sat, 10 Jan 2026 00:28:49 +0000 Subject: [PATCH] viona: FFI out of bounds fix `vioc_intr_poll_mq` needs to have space for twice the number of queue pairs, not the number of pairs, since interrupts are per-queue, not per-pair. --- crates/viona-api/header-check/build.rs | 3 ++- crates/viona-api/src/ffi.rs | 11 ++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/crates/viona-api/header-check/build.rs b/crates/viona-api/header-check/build.rs index fb48ff399..b2a7b374c 100644 --- a/crates/viona-api/header-check/build.rs +++ b/crates/viona-api/header-check/build.rs @@ -36,7 +36,8 @@ fn main() { cfg.skip_field(move |name, field| match (name, field) { // C header currently lacks explicit pad fields - ("vioc_ring_init", "_pad") => true, + ("vioc_intr_poll_mq", "_pad") => true, + ("vioc_ring_init_modern", "_pad") => true, ("vioc_ring_msi", "_pad") => true, _ => false, diff --git a/crates/viona-api/src/ffi.rs b/crates/viona-api/src/ffi.rs index bf076afe9..e67f97d11 100644 --- a/crates/viona-api/src/ffi.rs +++ b/crates/viona-api/src/ffi.rs @@ -57,20 +57,25 @@ mod test { } /// The minimum number of queue pairs supported by a device. -pub const VIONA_MIN_QPAIRS: usize = 1; +pub const VIONA_MIN_QPAIR: usize = 1; /// The maximum number of queue pairs supported by a device. /// /// Note that the VirtIO limit is much higher (0x8000); Viona artificially /// limits the number to 256 pairs, which makes it possible to implmeent /// interrupt notification with a reasonably sized bitmap. -pub const VIONA_MAX_QPAIRS: usize = 0x100; +pub const VIONA_MAX_QPAIR: usize = 0x100; const fn howmany(x: usize, y: usize) -> usize { assert!(y > 0); x.div_ceil(y) } +/// The number of 32-bit words required to detect interrupts for the maximum +/// number of supported queue pairs. Note the factor of two here: interrupts +/// are per-queue, not per-pair. +pub const VIONA_INTR_WORDS: usize = howmany(VIONA_MAX_QPAIR * 2, 32); + #[repr(C)] pub struct vioc_create { pub c_linkid: u32, @@ -102,7 +107,7 @@ pub struct vioc_ring_msi { pub struct vioc_intr_poll_mq { pub vipm_nrings: u16, pub _pad: u16, - pub vipm_status: [u32; howmany(VIONA_MAX_QPAIRS, 32)], + pub vipm_status: [u32; VIONA_INTR_WORDS], } #[repr(C)]