https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=297437
Bug ID: 297437
Summary: netmap: unchecked NR_REG_NULL slot count overflows
ring allocation size
Product: Base System
Version: 14.4-STABLE
Hardware: amd64
OS: Any
Status: New
Severity: Affects Some People
Priority: ---
Component: kern
Assignee: [email protected]
Reporter: [email protected]
Created attachment 273624
--> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=273624&action=edit
Deterministic two-call RX slot-count overflow reproducer
Overview
========
The NETMAP_REQ_REGISTER path for an NR_REG_NULL adapter accepts
user-controlled TX/RX ring and slot counts without applying the geometry
bounds used by other netmap adapter types.
A slot count of 0xfffffffe reaches netmap_mem2_rings_create(), where the ring
allocation length is calculated in a 32-bit u_int. The multiplication and
addition wrap to a small allocation size. The kernel then initializes or
traverses the allocation using the original slot count, causing an
out-of-bounds kernel memory access and panic.
Both the RX-slot and TX-slot variants reproduced deterministically.
Tested environment
==================
Operating system: FreeBSD 14.4-STABLE
Architecture: amd64
Kernel ident: SYZKALLER
Base image source revision: cc921088d9ee
Base image date: 2026-05-14
Virtualization: QEMU/KVM
The kernel is based on the FreeBSD 14.4-STABLE amd64 image identified by
revision cc921088d9ee, with the SYZKALLER kernel
configuration/instrumentation.
The reported reproductions were performed as root in clean snapshot VMs.
Unprivileged-user and jail reachability have not been tested.
Reproducer
==========
The attached RX .syz reproducer executes two calls:
r0 = openat$netmap(...)
ioctl$NIOCCTRL(r0, NIOCCTRL, {
nr_reqtype = NETMAP_REQ_REGISTER,
nr_name = "null-overflow-rx",
nr_mode = NR_REG_NULL,
nr_mem_id = 1,
nr_tx_slots = 0x10,
nr_rx_slots = 0xfffffffe
})
The attached TX variant exchanges the slot counts:
nr_tx_slots = 0xfffffffe
nr_rx_slots = 0x10
The RX program panicked on its first execution in two independent cold boots.
The TX program panicked on its first execution in a third independent cold
boot.
Observed result
===============
All three deterministic runs produced:
panic: vm_fault_lookup: fault on nofault entry,
addr: 0xfffffe007bc00000
Relevant stack:
panic
vm_fault
vm_fault_trap
trap_pfault
netmap_mem_rings_create+0x84
netmap_do_regif+0x5b3
netmap_ioctl+0x1cf0
freebsd_netmap_ioctl+0xa5
devfs_ioctl
vn_ioctl
kern_ioctl
sys_ioctl
The same fault address was observed in both RX cold-boot runs and in the
independent TX cold-boot run.
Expected result
===============
The kernel should reject or safely bound invalid ring geometry. A
user-controlled slot count must not overflow the kernel allocation length or
cause an out-of-bounds kernel memory access.
Root cause
==========
netmap_get_null_na() copies all four geometry values from the
nmreq_register request without applying the nm_bound_var() checks used by
VALE, pipe, and monitor adapters:
nna->up.num_tx_rings = req->nr_tx_rings;
nna->up.num_rx_rings = req->nr_rx_rings;
nna->up.num_tx_desc = req->nr_tx_slots;
nna->up.num_rx_desc = req->nr_rx_slots;
The minimal reproducer selects the existing default allocator with
nr_mem_id = 1.
The unchecked slot count is copied to kring->nkr_num_slots. In
netmap_mem2_rings_create(), the allocation length is calculated using
32-bit u_int variables:
u_int len, ndesc;
ndesc = kring->nkr_num_slots;
len = sizeof(struct netmap_ring) +
ndesc * sizeof(struct netmap_slot);
For ndesc = 0xfffffffe, this expression wraps in 32 bits. A small allocation
can consequently be returned and later accessed as if it contained almost
UINT32_MAX slots.
This is an arithmetic and validation bug, rather than a normal allocation
failure.
Suggested fix
=============
Two layers of validation are suggested:
1. Apply explicit ring-count and slot-count limits in netmap_get_null_na(),
consistent with the bounds applied to other software adapter types.
2. Add a common integer-overflow check in netmap_mem2_rings_create() before
calculating:
sizeof(struct netmap_ring) +
ndesc * sizeof(struct netmap_slot)
A proposed stable/14 patch is attached. It has not yet been tested against
FreeBSD main and is provided for discussion rather than as a final reviewed
fix.
Impact
======
The demonstrated impact is a deterministic local kernel panic and an
out-of-bounds kernel memory access caused by an integer-overflowed allocation
size.
Because the issue involves kernel memory corruption, a stronger security
impact may be possible, but exploitability has not been assessed.
Triggering the issue requires access to /dev/netmap. The reproductions
reported here were performed as root. Default unprivileged and jail
reachability have not been tested.
Affected branches
=================
The issue was reproduced on stable/14. Source review found the same relevant
unchecked NULL-adapter geometry and 32-bit allocation calculation in the
corresponding current netmap code, but the panic has not yet been reproduced
on FreeBSD main.
Reproduction evidence
=====================
Three independent clean cold-boot runs are attached:
1. RX slot overflow, first run:
SHA-256:
ca04e711334b9d78d4ee501eae130678b9e7e5b89a193b2077569b0f1b7dedae
2. RX slot overflow, second run:
SHA-256:
b4b51888a18eb6c37d0b4b2b48abbfa08283f8e8c7f61ffe2eebaf8fcb13bb2
3. TX slot overflow:
SHA-256:
f7cff58b82631f92dc2850b0c9e827b4118084431b5367980ecbefd2ddb484eb
Tools used
==========
The issue was discovered and reproduced using syzkaller with locally
developed FreeBSD netmap syscall descriptions and structured seed programs.
AI-assisted tools were used to organize experiment artifacts, inspect crash
logs, group related crash signatures, and help draft this report. The
reproduction results, fault locations, arithmetic analysis, and source-level
claims were manually checked against the saved kernel image and source tree.
--
You are receiving this mail because:
You are the assignee for the bug.
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.