DF-3440 / verdict.json
{ "finding_id": "DF-3440", "status": "not_reproduced", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "div_output() reads sin_port (offset 4..8) and sin_addr (8..12) from a user sendto() sockaddr allocated with as few as 4 bytes; the reads provably execute (sendto with 4/9-byte sockaddr succeeds and the packet is reinjected), and the OOB bytes steer the re-inject direction and the ipfw resume rule. Deterministic value control or readback could not be produced on this guest: counter oracles are per-CPU/noisy, ipfw hooks are ether-layer-only so loopback reinjects never re-match a divert rule, one_pass resume points equal the OOB bytes themselves, and slab grooming does not reliably land (same verified experience as DF-3357 on this allocator).", "exploit_chain": "", "evidence": [ "findings/poc/DF-3440/run.log \u2014 12+ successful under-sized sendto shots + oracle diagnosis", "findings/poc/DF-3440/divsteer.c divleak.c div3440.c \u2014 three oracle designs" ], "kernel_refs": [ "sys/netinet/ip_divert.c:317-373", "sys/netinet/ip_divert.c:344-350", "sys/netinet/ip_divert.c:494-508", "sys/kern/uipc_syscalls.c:1513-1532" ], "poc_changes": "Three oracle variants were built (netstat counters, ipfw2-divert skipto readback, groom+usched_set-pinned steering); none produced a deterministic observable for the OOB byte values.", "attempts": 6, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #1 x86_64 (divert code identical to stock #0; patch under test touched only ipfw3)", "runtime_sec": 1500, "guest_dirty": 0, "build_cmd": "cc -O -o div3440 div3440.c; cc -O -o divleak divleak.c; cc -O -o divsteer divsteer.c", "run_cmd": "./div3440; ./divleak (with ipfw divert rule 8675); ./divsteer", "code_hash": "e412eb752375ffad5b3c5c37e6982d5f743dbd77047a28d1a6688e8d41766fec", "notes": "Same class as DF-0650 (rip_send, Medium) and DF-3357 (udp_send, verified leak) \u2014 divert is the only one of the three whose readback channels are structurally blocked on this system (ether-only ipfw hooks + one_pass semantics).", "recommended_fix": "In div_send (or at div_output entry), reject nam->sa_len != sizeof(struct sockaddr_in) with EINVAL before any field read; do not trust sin_port/sin_addr from short sockaddrs." } |