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: [email protected]
Reporter: [email protected]
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.
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.