[Bug 297436] netmap: signed nr_port_idx causes out-of-bounds access in netmap_vale_list()
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 297436] netmap: signed nr_port_idx causes out-of-bounds access in netmap_vale_list()"
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 297436] netmap: signed nr_port_idx causes out-of-bounds access in netmap_vale_list()"
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 297436] netmap: signed nr_port_idx causes out-of-bounds access in netmap_vale_list()"
- Reply: bugzilla-noreply_a_freebsd.org: "[Bug 297436] netmap: signed nr_port_idx causes out-of-bounds access in netmap_vale_list()"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 11 Aug 2026 13:16:39 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=297436
Bug ID: 297436
Summary: netmap: signed nr_port_idx causes out-of-bounds access
in netmap_vale_list()
Product: Base System
Version: 14.4-STABLE
Hardware: amd64
OS: Any
Status: New
Severity: Affects Some People
Priority: ---
Component: kern
Assignee: bugs@FreeBSD.org
Reporter: yangyang20250212@163.com
Created attachment 273622
--> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=273622&action=edit
netmap: signed nr_port_idx causes out-of-bounds access in netmap_vale_list()C
reproducer
Overview
========
The NETMAP_REQ_VALE_LIST request accepts nr_port_idx as a uint32_t, but
netmap_vale_list() assigns it to a signed int and subsequently uses it as an
array index without validating that it is non-negative.
On amd64, values greater than INT_MAX become negative after the conversion.
A request with nr_port_idx = 0x80000000 therefore causes an out-of-bounds
access to b->bdg_ports[j] and a kernel page fault.
Tested environment
==================
Operating system: FreeBSD 14.4-STABLE
Architecture: amd64
Kernel configuration: <fill in>
Kernel source commit: <fill in>
uname -a: <fill in>
The issue was reproduced in a clean QEMU/KVM virtual machine.
Reproducer
==========
The attached native C program performs:
1. open("/dev/netmap", O_RDWR)
2. NIOCCTRL with:
- nr_reqtype = NETMAP_REQ_VALE_LIST
- nr_port_idx = 0x80000000
Compile and execute on FreeBSD:
cc -Wall -O2 -o netmap_vale_list_oob manual_negative_port_idx.c
./netmap_vale_list_oob
The trigger caused the same kernel panic on the first execution in two
independent cold boots.
Observed result
===============
Fatal trap 12: page fault while in kernel mode
The deterministic runs had:
instruction pointer: 0xffffffff80a26750
fault address: 0xfffffdfc0ccd0828
function: netmap_vale_list+0x150
caller: netmap_ioctl+0xe3e
Relevant stack:
panic
trap_pfault
netmap_vale_list+0x150
netmap_ioctl+0xe3e
freebsd_netmap_ioctl
devfs_ioctl
vn_ioctl
kern_ioctl
sys_ioctl
Expected result
===============
The kernel should reject an out-of-range nr_port_idx and return an error. A
user-supplied request must not cause an out-of-bounds kernel array access or
panic.
Root cause
==========
nr_port_idx is defined as uint32_t, but netmap_vale_list() stores it in the
signed variable j:
int error = 0, i, j;
j = req->nr_port_idx;
The loop checks only:
j < NM_BDG_MAXPORTS
It does not check j >= 0. After conversion, 0x80000000 becomes a negative
signed int on the tested amd64 kernel and is used directly in:
b->bdg_ports[j]
Suggested fix
=============
Keep the port index unsigned, or explicitly reject values greater than
INT_MAX / outside the valid port range before indexing the array.
A proposed stable/14 patch is attached. It changes j from int to uint32_t.
The patch has not yet been tested against FreeBSD main.
Impact
======
The demonstrated impact is a local kernel panic and out-of-bounds kernel
memory access. Exploitability has not been assessed.
Triggering the issue requires access to /dev/netmap. The reproductions were
performed as <root/non-root -- fill in the actual result>. I have not yet
determined whether the issue is reachable by an unprivileged user under the
default device permissions or from a jail.
Affected branches
=================
The issue was reproduced on stable/14. The corresponding source pattern
appears to be present in FreeBSD main, but I have not yet reproduced the
panic
on main.
Tools used
==========
The issue was initially discovered using syzkaller with locally developed
FreeBSD netmap syscall descriptions and structured seeds. The final native C
reproducer does not require syzkaller.
AI-assisted tools were used to help organize experiment artifacts, inspect
crash logs, and draft the report. The fault location, source-level analysis,
and reproduction results were manually checked against the saved kernel
image and source tree
--
You are receiving this mail because:
You are the assignee for the bug.