Skip to content

Commit 6b61062

Browse files
committed
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.
1 parent 9a3a93a commit 6b61062

File tree

2 files changed

+10
-4
lines changed

2 files changed

+10
-4
lines changed

crates/viona-api/header-check/build.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ fn main() {
3636

3737
cfg.skip_field(move |name, field| match (name, field) {
3838
// C header currently lacks explicit pad fields
39-
("vioc_ring_init", "_pad") => true,
39+
("vioc_intr_poll_mq", "_pad") => true,
40+
("vioc_ring_init_modern", "_pad") => true,
4041
("vioc_ring_msi", "_pad") => true,
4142

4243
_ => false,

crates/viona-api/src/ffi.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,20 +57,25 @@ mod test {
5757
}
5858

5959
/// The minimum number of queue pairs supported by a device.
60-
pub const VIONA_MIN_QPAIRS: usize = 1;
60+
pub const VIONA_MIN_QPAIR: usize = 1;
6161

6262
/// The maximum number of queue pairs supported by a device.
6363
///
6464
/// Note that the VirtIO limit is much higher (0x8000); Viona artificially
6565
/// limits the number to 256 pairs, which makes it possible to implmeent
6666
/// interrupt notification with a reasonably sized bitmap.
67-
pub const VIONA_MAX_QPAIRS: usize = 0x100;
67+
pub const VIONA_MAX_QPAIR: usize = 0x100;
6868

6969
const fn howmany(x: usize, y: usize) -> usize {
7070
assert!(y > 0);
7171
x.div_ceil(y)
7272
}
7373

74+
/// The number of 32-bit words required to detect interrupts for the maximum
75+
/// number of supported queue pairs. Note the factor of two here: interrupts
76+
/// are per-queue, not per-pair.
77+
pub const VIONA_INTR_WORDS: usize = howmany(VIONA_MAX_QPAIR * 2, 32);
78+
7479
#[repr(C)]
7580
pub struct vioc_create {
7681
pub c_linkid: u32,
@@ -102,7 +107,7 @@ pub struct vioc_ring_msi {
102107
pub struct vioc_intr_poll_mq {
103108
pub vipm_nrings: u16,
104109
pub _pad: u16,
105-
pub vipm_status: [u32; howmany(VIONA_MAX_QPAIRS, 32)],
110+
pub vipm_status: [u32; VIONA_INTR_WORDS],
106111
}
107112

108113
#[repr(C)]

0 commit comments

Comments
 (0)