[Bug 283860] nlattr_get_multipath() loop executes too many times if rtnh_len is zero

From: <bugzilla-noreply_at_freebsd.org>
Date: Sun, 05 Jan 2025 14:01:26 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=283860

            Bug ID: 283860
           Summary: nlattr_get_multipath() loop executes too many times if
                    rtnh_len is zero
           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 #256438 text/plain
         mime type:

Created attachment 256438
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=256438&action=edit
cause nlattr_get_multipath() to execute loop indefinitely

If a program calls netlink() NETLINK_ROUTE RTM_NEWROUTE with an
RTA_MULTIPATH TLV whose first rtnexthop has rtnh_len of zero, the
"for" loop in nlattr_get_multipath() will execute too many times,
since the "data_len -= len" won't actually decrease data_len.

Each iteration increments mp->num_hops, so that there's the
possibility of nl_parser_header() writing off the end of the space
allocated for mp.

A similar scenario results if rtnh_len is 65533, so that this line
yields len = 0 (since rtnh_len is unsigned short):

                int len = NL_ITEM_ALIGN(rtnh->rtnh_len);

I've attached a demo. On one of my machines it does write off the end
of allocated space and causes a redzone panic. But even without that
one can see the problem by turning on netlink debugging output.

# uname -a
FreeBSD xxx 15.0-CURRENT FreeBSD 15.0-CURRENT #25 main-n274459-9ba7351fcfd7:
Sun Dec 29 16:47:27 AST 2024    
root@xxx:/usr/obj/usr/src/amd64.amd64/sys/GENERIC amd64
# cc netlink14b.c
# sysctl -w net.netlink.debug.nl_parser_debug_level=100
# sysctl -w net.netlink.debug.nl_route_debug_level=100
# ./a.out
[nl_parser] nl_parse_attrs_raw: parse 0xfffff800432b7038 remaining_len 100
[nl_parser] nl_parse_attrs_raw: >> parsing 0xfffff800432b7038 attr_type 1 len 8
(rem 100)
[nl_parser] nl_parse_attrs_raw: >> parsing 0xfffff800432b7040 attr_type 9 len
12 (rem 92)
[nl_parser] nl_parse_attrs_raw: parse 0xfffff800432b7104 remaining_len 0
[nl_parser] nl_parse_attrs_raw: end parse: 0 remaining_len 0
[nl_parser] nl_parse_attrs_raw: parse 0xfffff800432b7114 remaining_len 0
[nl_parser] nl_parse_attrs_raw: end parse: 0 remaining_len 0
[nl_parser] nl_parse_attrs_raw: parse 0xfffff800432b7124 remaining_len 0
[nl_parser] nl_parse_attrs_raw: end parse: 0 remaining_len 0
... many more ...
[nl_parser] nl_parse_attrs_raw: parse 0xfffff800432b7504 remaining_len 0
[nl_parser] nl_parse_attrs_raw: end parse: 0 remaining_len 0
[nl_parser] nl_parse_attrs_raw: parse 0xfffff800432b7514 remaining_len 0
[nl_parser] nl_parse_attrs_raw: end parse: 0 remaining_len 0
[nl_route] PID 9005 nlattr_get_multipath: RTA_MULTIPATH: nexhop 66: parse
failed
[nl_parser] nl_parse_attrs_raw: parse failed at offset 36

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