[Bug 295106] nl_get_attrs_bmask_raw() can read off the end of its input buffer

From: <bugzilla-noreply_at_freebsd.org>
Date: Fri, 08 May 2026 18:39:29 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=295106

            Bug ID: 295106
           Summary: nl_get_attrs_bmask_raw() can read off the end of its
                    input buffer
           Product: Base System
           Version: CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: rtm@lcs.mit.edu
 Attachment #270522 text/plain
         mime type:

Created attachment 270522
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=270522&action=edit
tickle a bug in nl_get_attrs_bmask_raw()

This code in netlink_message_parser.h will pass a negative len to
nl_get_attrs_bmask_raw() if hdr->nlmsg_len is 31 and it is called from
rtnl_handle_newlink() with ifmsg_parser, whose nl_hdr_off is 16.

static inline void
nl_get_attrs_bmask_nlmsg(struct nlmsghdr *hdr,
    const struct nlhdr_parser *parser, struct nlattr_bmask *bm)
{
        nl_get_attrs_bmask_raw(
            (struct nlattr *)((char *)(hdr + 1) + parser->nl_hdr_off),
            hdr->nlmsg_len - sizeof(*hdr) - parser->nl_hdr_off, bm);
}

But nl_get_attrs_bmask_raw()'s len argument is declared unsigned,
and will in this case be huge, so that this loop can run too
many times:

        NLA_FOREACH(nla, nla_head, len) {

I've attached a demo program.

# uname -a
FreeBSD xxx 16.0-CURRENT FreeBSD 16.0-CURRENT #35 main-n275527-1a9c5d7499c3:
Fri May  8 13:21:19 AST 2026    
root@xxx:/usr/obj/usr/src/amd64.amd64/sys/GENERIC amd64
# cc netlink7b.c
# ./a.out
panic: vm_fault_lookup: fault on nofault entry, addr: 0xfffffe0123b05000
cpuid = 8
time = 1778265196
KDB: stack backtrace:
db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe00d7216700
vpanic() at vpanic+0x149/frame 0xfffffe00d7216830
panic() at panic+0x43/frame 0xfffffe00d7216890
vm_fault() at vm_fault+0x1c1a/frame 0xfffffe00d7216a10
vm_fault_trap() at vm_fault_trap+0x65/frame 0xfffffe00d7216a50
trap_pfault() at trap_pfault+0x275/frame 0xfffffe00d7216ac0
calltrap() at calltrap+0x8/frame 0xfffffe00d7216ac0
--- trap 0xc, rip = 0xffffffff80eab391, rsp = 0xfffffe00d7216b90, rbp =
0xfffffe00d7216bb0 ---
nl_get_attrs_bmask_raw() at nl_get_attrs_bmask_raw+0x51/frame
0xfffffe00d7216bb0
rtnl_handle_newlink() at rtnl_handle_newlink+0xb3/frame 0xfffffe00d7216ca0
rtnl_handle_message() at rtnl_handle_message+0x195/frame 0xfffffe00d7216d00
nl_receive_message() at nl_receive_message+0x11c/frame 0xfffffe00d7216d40
nl_taskqueue_handler() at nl_taskqueue_handler+0x3f5/frame 0xfffffe00d7216e40
taskqueue_run_locked() at taskqueue_run_locked+0x1ce/frame 0xfffffe00d7216ec0
taskqueue_thread_loop() at taskqueue_thread_loop+0xd3/frame 0xfffffe00d7216ef0
fork_exit() at fork_exit+0x82/frame 0xfffffe00d7216f30
fork_trampoline() at fork_trampoline+0xe/frame 0xfffffe00d7216f30
--- trap 0, rip = 0, rsp = 0, rbp = 0 ---
KDB: enter: panic

-- 
You are receiving this mail because:
You are the assignee for the bug.