[Bug 283797] netlink's npt_clear() should set npt->cookie = 0
Date: Thu, 02 Jan 2025 16:31:37 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=283797 Bug ID: 283797 Summary: netlink's npt_clear() should set npt->cookie = 0 Product: Base System Version: Unspecified Hardware: Any OS: Any Status: New Severity: Affects Some People Priority: --- Component: kern Assignee: bugs@FreeBSD.org Reporter: rtm@lcs.mit.edu Attachment #256345 text/plain mime type: Created attachment 256345 --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=256345&action=edit demonstrate a bug in netlink's npt_clear() npt_clear() in sys/netlink/netlink_io.c zeroes npt->lb, but leaves npt->cookie unchanged. Since npt->cookie (if non-NULL) points into npt->lb, this means that npt_clear() can leave a non-NULL npt->cookie pointing to zeroed contents. As a result, if nl_process_nbuf() takes more than one trip through its for loop, on the second &c trip npt->cookie can be non-NULL even though npt->cookie->nla_len is zero. This can cause nlmsg_ack()'s call to nlattr_add_raw(nw, npt->cookie) to execute return (nlattr_add(nw, nla_src->nla_type, nla_src->nla_len - sizeof(struct nlattr), (const void *)(nla_src + 1))); which (since nla_src->nla_len is zero) will pass attr_len=65532 to nlattr_add. With an INVARIANTS kernel, this will cause an MPASS() or KASSERT() failure. On an ordinary kernel, it will cause nlattr_add() to memcpy off the end of the allocated nw->buf. I've attached a demo. # uname -a FreeBSD 15.0-CURRENT FreeBSD 15.0-CURRENT #335 main-n250995-3750873316a1-dirty: Thu Jan 2 11:25:30 EST 2025 rtm@xxx:/usr/obj/usr/rtm/symbsd/src/riscv.riscv64/sys/RTM riscv # cc netlink4c.c # ./a.out tap0: Ethernet address: da:2e:d7:ce:2d:57 tap0: promiscuous mode enabled REDZONE: Buffer overflow detected. 16 bytes corrupted after 0xffffffc09e011020 (65568 bytes allocated). Allocation backtrace: #0 0xffffffc000617370 at redzone_setup+0xa0 #1 0xffffffc0002d4da8 at malloc_large+0x90 #2 0xffffffc0002d4bc4 at malloc+0x120 #3 0xffffffc00052bad4 at nl_buf_alloc+0x2a #4 0xffffffc00052ca02 at _nlmsg_refill_buffer+0xb2 #5 0xffffffc00052d11e at nlmsg_ack+0x3a6 #6 0xffffffc00052bfca at nl_taskqueue_handler+0x32a #7 0xffffffc000357070 at taskqueue_run_locked+0x158 #8 0xffffffc000357d74 at taskqueue_thread_loop+0xd4 #9 0xffffffc0002ba19c at fork_exit+0x68 #10 0xffffffc0006785ea at fork_trampoline+0xa Free backtrace: #0 0xffffffc00061773a at redzone_check+0x344 #1 0xffffffc0002d5bac at free_dbg+0x5c #2 0xffffffc0002d4976 at free+0x1c #3 0xffffffc00052bb1c at nl_buf_free+0x14 #4 0xffffffc00052a85c at nl_close+0x1ca #5 0xffffffc00038e438 at soclose+0xba #6 0xffffffc00036cd88 at soo_close+0x20 #7 0xffffffc0002a1f8e at _fdrop+0x16 #8 0xffffffc0002a55d8 at closef+0x1b0 #9 0xffffffc0002a4ca4 at fdescfree+0x4ea #10 0xffffffc0002b55bc at exit1+0x40a #11 0xffffffc0002b51ae at sys_exit+0x10 #12 0xffffffc00067913a at do_trap_user+0x1e0 #13 0xffffffc000666b12 at cpu_exception_handler_user+0x72 panic: Stopping here. -- You are receiving this mail because: You are the assignee for the bug.