β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-3292

SIOCS80211 MESH_RTCMD ADD/DELETE dereference the raw user-supplied ireq->i_data pointer in kernel (no copyin)

Summary

mesh_ioctl_set80211's MESH_RTCMD_DELETE passes ireq->i_data straight into ieee80211_mesh_rt_del whose IEEE80211_ADDR_EQ (memcmp) reads 6 bytes from the pointer in kernel context with no copyin; the ADD path's pre-checks also deref i_data raw (its later copyin is correct). i_data is a fully user-controlled pointer (SIOCS80211 gated by SYSCAP_NONET_WIFI). VERIFIED: MESH_RTCMD_DELETE with i_data = 0xffffffff40000000 -> Fatal trap 12 (stopped at bcmp+0x3c); first attempt with 0xffffffff81234000 did NOT fault (mapped kernel memory) - confirming the arbitrary-kernel-address 6-byte read oracle (route-deleted-or-not side channel). Privileged local. Fix: copyin the address once at the top of the case (one-line discipline fix mirroring the ADD path; not in the validated kernel).

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3292 Β· 7 files
FileTypeDescriptionSize
README.md β€” 2.1 KB ↓ raw
VERDICT.md β€” 1.5 KB ↓ raw
run.sh β€” 111 B view raw
setmeshdel.c β€” 2.0 KB view raw
panic.txt β€” 658 B view raw
verdict.json β€” 2.5 KB view raw
manifest.json β€” 496 B view raw

DF-3292 β€” SIOCS80211 MESH_RTCMD ADD/DELETE dereference the user-supplied ireq->i_data pointer directly in kernel

File: sys/netproto/802_11/wlan/ieee80211_mesh.c (pass 2 audit)

What

mesh_ioctl_set80211 (:3653-3663):

case IEEE80211_MESH_RTCMD_ADD:
        if (IEEE80211_ADDR_EQ(vap->iv_myaddr, ireq->i_data) ||   /* raw user ptr */
            IEEE80211_ADDR_EQ(broadcastaddr, ireq->i_data))      /* raw user ptr */
                return EINVAL;
        error = copyin(ireq->i_data, &tmpaddr, IEEE80211_ADDR_LEN);  /* proper copyin AFTER */
        ...
case IEEE80211_MESH_RTCMD_DELETE:
        ieee80211_mesh_rt_del(vap, ireq->i_data);                /* raw user ptr, NO copyin at all */

IEEE80211_ADDR_EQ reads 6 bytes from i_data in kernel context. i_data is a user-controlled pointer from the ioctl (SIOCS80211, requires SYSCAP_NONET_WIFI β€” checked at ieee80211_ioctl.c:3472).

Consequences for a privileged caller: * passing an invalid/unmapped kernel address β†’ kernel page fault β†’ panic (privileged local DoS; verified at runtime, see below); * passing any mapped kernel address β†’ 6 bytes of arbitrary kernel memory compared against routing-table destinations β€” an arbitrary-address 6-byte read gadget whose side effect (route deleted or not) is observable, i.e. a constrained kernel-memory oracle; * on the DELETE path there is no copyin at all β€” robustness/standards bug (user pages must not be dereferenced directly; breaks under SMAP-capable platforms and colliding mappings).

Runtime (fixed-kernel guest β€” bug path untouched by the 7-fix diff)

# ./setmeshdel wlan0
issuing MESH_RTCMD_DELETE with kernel i_data=0xffffffff81234000...
Fatal trap 12: page fault while in kernel mode
fault virtual address = 0xffffffff81234000

(panic.txt)

Build / run

sh findings/poc/DF-3286/build.sh && vm.sh run_root "cc -o /root/fwm/setmeshdel /root/fwm/setmeshdel.c"
sh findings/poc/DF-3292/run.sh

Fix

copyin the 6-byte address first, compare/delete the kernel copy (same discipline the ADD path uses after its check).

Severity Low (privileged-only, but a raw user/kernel-pointer deref). CWE-822.

VERDICT.md
↓ download raw

DF-3292 VERDICT β€” REPRODUCED (privileged local panic; raw user-pointer deref in kernel)

Reproduction (fixed-kernel guest; the 7-fix diff does not touch this path)

Mesh vap up; root runs:

# ./setmeshdel wlan0
issuing MESH_RTCMD_DELETE with kernel i_data=0xffffffff81234000...

Serial console:

Fatal trap 12: page fault while in kernel mode
fault virtual address = 0xffffffff81234000
...ieee80211_mesh_rt_del / mesh_ioctl_set80211 trace...
(see panic.txt)

Root cause certain from source: mesh.c:3663 passes ireq->i_data (user-controlled pointer) straight into ieee80211_mesh_rt_del which reads 6 bytes from it (IEEE80211_ADDR_EQ at :377) with no copyin; the ADD path's pre-check at :3654 derefs i_data raw as well (its later copyin is correct). Requires SYSCAP_NONET_WIFI (SIOCS80211 gate at ieee80211_ioctl.c:3472) β†’ privileged local DoS + arbitrary-kernel- address 6-byte read oracle (route-deleted/not side channel).

Impact ceiling

Privileged panic + constrained kernel read oracle; robustness defect (direct user-page deref). Low severity.

Fix status (batch validation)

Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.

(No fix.diff for this item: documented recommendation only - see Fix above.)

Fix verification

not_testable
baseline reproduced→ patch + rebuild →patched clean

no fix authored for this Low finding in the combined kernel (one-line copyin fix in the recommended_fix)

[]
per-fix-DF-3292

Confirmed kernel references

Detail

Exploit chain

privileged process: ioctl ADD (valid buffer) seeds a route -> ioctl DELETE with i_data = chosen kernel address -> kernel memcmp(rt_dest, kernel_addr, 6) -> page fault panic on unmapped address, or a 6-byte equality oracle (deletes route on match) on mapped addresses

Evidence (decisive lines)

panic.txt: Fatal trap 12, fault VA 0xffffffff40000000, Stopped at bcmp+0x3c

PoC changes

tool first seeds a route via the ADD ioctl (empty table skips the loop entirely), then DELETEs with an unmapped kernel address; first address choice 0xffffffff81234000 did not fault (mapped), 0xffffffff40000000 does

Verified recommended fix

copyin(ireq->i_data, tmpaddr, IEEE80211_ADDR_LEN) once at the top of the RTCMD case and use tmpaddr for both the EQ checks and rt_del

Verdict

mesh_ioctl_set80211 passes the raw user-supplied ireq->i_data pointer to ieee80211_mesh_rt_del (mesh.c:3663) and to IEEE80211_ADDR_EQ pre-checks (:3654) with no copyin; the DELETE path dereferences it in-kernel (memcmp at :377). Seeding one route via MESH_RTCMD_ADD then issuing DELETE with i_data=0xffffffff40000000 faults the kernel: Fatal trap 12, supervisor read, fault VA 0xffffffff40000000, stopped at bcmp+0x3c (see panic.txt). Privileged-only (SIOCS80211 requires SYSCAP_NONET_WIFI): local DoS plus an arbitrary-kernel-address 6-byte read oracle (route-deleted vs not is observable).