DF-0720 / ng_sppp_harness.c
/* * DF-0720 โ structural demonstration of the ng_sppp if_alloc(IFT_PPP) heap * overflow. The vulnerable file (sys/netgraph7/ng_sppp.c) does NOT compile on * this kernel (IFP2SP/SP2IFP are undefined anywhere in sys/), so this bug is * LATENT / dead code โ it cannot be triggered live. * * This harness models the structural invariant the bug violates: * - if_alloc(IFT_PPP) allocates ONLY sizeof(struct ifnet) (if.c:3083) * - sppp_attach(ifp) casts that pointer to (struct sppp*) and writes fields * that live PAST sizeof(struct ifnet), because struct sppp nests * struct arpcom (which itself nests struct ifnet) as its FIRST member, * then adds ~1KB of PPP state. * * Model: BASE = sizeof(ifnet); sppp fields live at offset [BASE .. BASE+EXTRA). * Writing them into a BASE-sized allocation corrupts [BASE .. BASE+EXTRA). */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> /* Approximate structural offsets (real kernel: struct ifnet ~ 512-700 bytes, * struct arpcom = ifnet + 6 enaddr + 1 vlan; struct sppp adds ~1KB). The exact * numbers do not matter โ the invariant sppp > ifnet is structural. */ #define IFNET_SIZE 600 #define SPPP_EXTRA 1024 #define SPPP_SIZE (IFNET_SIZE + SPPP_EXTRA) int main(void){ /* model the heap: [alloc(IFNET_SIZE)] [adjacent heap] */ uint8_t heap[SPPP_SIZE + 256]; memset(heap, 0x00, sizeof(heap)); memset(heap + IFNET_SIZE, 0xCC, sizeof(heap) - IFNET_SIZE); /* canary */ uint8_t *ifp = heap; /* if_alloc(IFT_PPP) result */ /* sppp_attach(ifp): struct sppp *sp = (struct sppp*) ifp; then writes * sp->pp_fastq, pp_cpq, pp_next, pp_seq[], pp_rseq[], state[], timeout[], * lcp, ipcp, ipv6cp, myauth, hisauth, pp_up/pp_down fn pointers, ... */ printf("if_alloc(IFT_PPP) returned %d-byte object (sizeof(struct ifnet))\n", IFNET_SIZE); printf("sppp_attach() casts to struct sppp* (%d bytes) and writes fields " "at offset [%d .. %d)\n", SPPP_SIZE, IFNET_SIZE, SPPP_SIZE); memset(ifp + IFNET_SIZE, 0xAB, SPPP_EXTRA); /* the sppp_attach writes */ int over = 0; for (int i = IFNET_SIZE; i < SPPP_SIZE; i++) if (heap[i] != 0xCC) over++; printf("bytes written past the %d-byte allocation into adjacent heap: %d\n", IFNET_SIZE, over); if (over > 0) printf("RESULT: STRUCTURAL OVERFLOW CONFIRMED โ sppp_attach writes " "~%d bytes past the if_alloc(IFT_PPP) object\n", over); else printf("RESULT: no overflow (model misconfigured)\n"); return (over > 0) ? 1 : 0; } |