DF-0490 / run.log
=== DF-0490 BASELINE run on UNPATCHED #0 kernel (6.5-DEVELOPMENT #0, Thu Jul 2) === Run as unprivileged maxx (uid=1001) on vtnet0: uid=1001 euid=1001 === SIOCGLIFADDR on vtnet0 (cmp=0 path) === SIOCGLIFADDR OK addr.ss_family = -1 (AF_INET=2 AF_INET6=28) addr.ss_len = 0 addr raw (len=128): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 prefixlen = 0 flags=0x0 [reference] SIOCGIFADDR vtnet0 -> 10.0.2.15 (the REAL IPv4 addr) === lo0 baseline (also type-confused) === SIOCGLIFADDR OK addr.ss_family = -1 addr.ss_len = 0 addr raw: all zeros [reference] SIOCGIFADDR lo0 -> 127.0.0.1 RUN_EXIT=0 --- Analysis (unpatched) --- SIOCGLIFADDR returns ss_family=-1, ss_len=0, all-zero data instead of the real IPv4 address 10.0.2.15. This is the type confusion: the loop at in.c:911 filters `!= AF_INET6`, so it SKIPS the IPv4 address (10.0.2.15) and MATCHES the IPv6 address (fe80::5054:ff:fe12:3456). The matched in6_ifaddr is then cast to in_ifaddr* (in.c:923). ia_addr is read from offset 312 (in_ifaddr layout) but the actual in6_ifaddr has ia_addr at offset 240 -- so the read lands inside in6_ifaddr.ia_dstaddr, where sin_len happens to be 0, so bcopy copies 0 bytes. Result: empty/wrong data returned to the unprivileged caller.