[PATCH v3] rust: pci: reject out-of-bounds IRQ vector indices

From: Sophon Z via B4 Relay

Date: Mon Aug 31 2026 - 03:23:18 EST


From: Sophon Z <aiqubits@xxxxxxxxxxx>

IrqVectorRegistration::index() accepts a usize and documents that
out-of-bounds indices return EINVAL, while pci_irq_vector() takes an
unsigned int.

Casting an index larger than u32::MAX wraps it before the PCI core can
validate it. In particular, u32::MAX + 1 becomes zero and can resolve to
the first allocated vector. Values that fit in u32 but exceed
MSI_MAX_INDEX can also reach msi_domain_get_virq() and trigger
WARN_ON_ONCE.

Check the index against the registration length before entering the C
API, and keep the usize-to-u32 conversion checked so the ABI boundary
does not rely on an unchecked cast.

Fixes: 2fb7755b0a7e ("rust: pci: resolve IRQ in index() and embed IrqRequest in IrqVector")

Signed-off-by: Sophon Z <aiqubits@xxxxxxxxxxx>
---
Changes in v3:
- Check the index against the allocated vector count before entering the C API.
- Keep the checked usize-to-u32 conversion and document the C-side warning.
- Link to v2: https://patch.msgid.link/20260831-fix-pci-irq-vector-index-truncation-v2-1-4030ea7746a9@xxxxxxxxxxx

Changes in v2:
- No code changes.
- Link to v1: https://patch.msgid.link/20260831-fix-pci-irq-vector-index-truncation-v1-1-d63217d99b67@xxxxxxxxxxx
---
rust/kernel/pci/irq.rs | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/rust/kernel/pci/irq.rs b/rust/kernel/pci/irq.rs
index 6741046ec1c0..dfab323f26f7 100644
--- a/rust/kernel/pci/irq.rs
+++ b/rust/kernel/pci/irq.rs
@@ -151,8 +151,14 @@ pub fn irq_type(&self) -> IrqType {
/// [`Self::len()`].
#[inline]
pub fn index(&self, index: usize) -> Result<IrqVector<'_>> {
+ if index >= self.len.get() {
+ return Err(EINVAL);
+ }
+
+ let index = u32::try_from(index).map_err(|_| EINVAL)?;
+
// SAFETY: `self.dev.as_raw()` is a valid pointer to a `struct pci_dev`.
- let irq = unsafe { bindings::pci_irq_vector(self.dev.as_raw(), index as u32) };
+ let irq = unsafe { bindings::pci_irq_vector(self.dev.as_raw(), index) };
if irq < 0 {
return Err(Error::from_errno(irq));
}

---
base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
change-id: 20260831-fix-pci-irq-vector-index-truncation-6752f3751a0d

Best regards,
--
Sophon Z <aiqubits@xxxxxxxxxxx>