DF-0636 / harness.c
/* * DF-0636 analysis: ng_tty ngt_rcvdata accesses sc->outq without tp->t_token * * Source: sys/netgraph7/tty/ng_tty.c:591-607 (ng7 โ DEAD CODE) * * ng7 code (vulnerable): * ngt_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) { * // ... NO lwkt_gettoken(&tp->t_token) ... * IF_QFULL(&sc->outq) // line 591: queue access WITHOUT token * IF_DROP(&sc->outq); // line 592 * IF_ENQUEUE(&sc->outq, m); // line 597: non-atomic queue mutation * qlen = sc->outq.ifq_len; // line 598 * * if (qlen == 1) { * lwkt_gettoken(&tp->t_token); // line 604: token acquired TOO LATE * ngt_start(sc->tp); * lwkt_reltoken(&tp->t_token); * } * } * * ngt_start(:412-439) dequeues IF_DEQUEUE WHILE holding token โ but * ngt_rcvdata already mutated the queue WITHOUT the token. * * v1 code (sys/netgraph/tty/ng_tty.c:568-594) is NOT VULNERABLE: * ngt_rcvdata correctly acquires lwkt_gettoken(&tp->t_token) at line 578 * BEFORE any queue access. v1 uses a different queue implementation * (custom mbuf queue with qtail/qlen, not struct ifqueue). * * STATUS: * - ng7 version: CONFIRMED VULNERABLE but DEAD CODE (not compiled on master) * - v1 version (ng_tty.ko, loadable): NOT VULNERABLE (has correct locking) * * This harness documents the analysis by comparing the two versions. */ #include <stdio.h> #include <string.h> int main(void) { printf("=== DF-0636: ng_tty ngt_rcvdata token race ===\n\n"); printf("FINDING FILED AGAINST: sys/netgraph7/tty/ng_tty.c:591-607\n\n"); printf("ng7 version (DEAD CODE โ not compiled on master):\n"); printf(" ngt_rcvdata (line 591-607):\n"); printf(" IF_QFULL(&sc->outq) // NO token held\n"); printf(" IF_ENQUEUE(&sc->outq, m) // NO token held\n"); printf(" qlen = sc->outq.ifq_len // NO token held\n"); printf(" lwkt_gettoken(&tp->t_token) // ACQUIRED TOO LATE (line 604)\n"); printf(" ngt_start(sc->tp)\n"); printf(" -> BUG CONFIRMED: queue mutated before token acquired\n"); printf(" -> Impact: SMP race -> queue corruption / UAF write\n\n"); printf("v1 version (sys/netgraph/tty/ng_tty.c โ ng_tty.ko, LOADABLE):\n"); printf(" ngt_rcvdata (line 568-594):\n"); printf(" lwkt_gettoken(&tp->t_token) // line 578: CORRECT โ before any access\n"); printf(" // all queue ops under token\n"); printf(" lwkt_reltoken(&tp->t_token) // line 590\n"); printf(" -> NOT VULNERABLE: correct locking\n\n"); printf("CONCLUSION:\n"); printf(" The bug exists in ng7 source but ng7 is dead code on master.\n"); printf(" The loadable v1 ng_tty.ko is NOT vulnerable (has correct locking).\n"); printf(" Impact: latent bug in dead code; fix for completeness.\n"); return 0; } |