[Bug 295102] inadequate bounds check in nlattr_get_multipath()

From: <bugzilla-noreply_at_freebsd.org>
Date: Fri, 08 May 2026 16:26:48 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=295102

            Bug ID: 295102
           Summary: inadequate bounds check in nlattr_get_multipath()
           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 #270516 text/plain
         mime type:

Created attachment 270516
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=270516&action=edit
cause kernel crash in nlattr_get_multipath()

In sys/netlink/route/rt.c nlattr_get_multipath(), this code is
meant to prevent user code from passing in a too-large
nethop array-element length:

                if (__predict_false(rtnh->rtnh_len <= sizeof(*rtnh) ||
                    rtnh->rtnh_len > data_len)) {

But the critical use of rtnh_len is:

                len = NL_ITEM_ALIGN(rtnh->rtnh_len);
                data_len -= len;

And the alignment can increase the value:

#define NL_ITEM_ALIGN_SIZE              sizeof(uint32_t)
#define NL_ITEM_ALIGN(_len)             __align_up(_len, NL_ITEM_ALIGN_SIZE)

The attached demo program supplies nla->nla_len 71, so data_len starts
out 67. The first rtnh_len is 65, which is < 67, but NL_ITEM_ALIGN
changes it to 68, so that after subtraction data_len wraps to 65535.
Then the loop writes beyond the end of mp->nhops[] into whatever was
allocated after it by npt_alloc(). The result (for me) is the kernel
dereferencing a garbage pointer and crashing.

panic: Fatal page fault at 0xffffffc00076de7e: 0x2000f0008020203                
cpu_exception_handler_supervisor() at cpu_exception_handler_supervisor+0x74     
--- exception 13, tval = 0x2000f0008020203                                      
post_p_rtnh() at post_p_rtnh+0x12                                               
nl_parse_header() at nl_parse_header+0xa2                                       
nlattr_get_multipath() at nlattr_get_multipath+0xb4                             
nl_parse_attrs_raw() at nl_parse_attrs_raw+0xb6                                 
nl_parse_header() at nl_parse_header+0x92                                       
rtnl_handle_newroute() at rtnl_handle_newroute+0x58                             
rtnl_handle_message() at rtnl_handle_message+0x12a                              
nl_taskqueue_handler() at nl_taskqueue_handler+0x49e                            
taskqueue_run_locked() at taskqueue_run_locked+0x158                            
taskqueue_thread_loop() at taskqueue_thread_loop+0xd4                           
fork_exit() at fork_exit+0x68                                                   
fork_trampoline() at fork_trampoline+0xa                                        
KDB: enter: panic                                                               

FreeBSD  16.0-CURRENT FreeBSD 16.0-CURRENT #10 main-n251024-dc4728f334c9-dirty:
Fri May  8 12:05:42 EDT 2026    
rtm@xxx:/usr/obj/usr/rtm/symbsd/src/riscv.riscv64/sys/RTM riscv

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