DF-2907 / dfv_boom.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | /* * dfv_boom.c — deterministic panic/wedge triggers. * dfv.d2966=1 : publish a half-initialized domain into the global domains * list (replicates the exact state of the kldload window * between uipc_domain.c:138 SLIST_INSERT_HEAD and :140 * net_init_domain). Then userland socket()+getpeername() * dispatches a NULL pru_peeraddr -> panic. * dfv.m2907=1 : md_get_mbuf(mdp, 128) on a 64-byte chain. On INVARIANTS * kernels m_copym KASSERTs; otherwise (production claim) * the ignored md_get_mem return yields silent success with * a short mbuf. */ #include <sys/param.h> #include <sys/kernel.h> #include <sys/systm.h> #include <sys/module.h> #include <sys/sysctl.h> #include <sys/mbuf.h> #include <sys/mchain.h> #include <sys/domain.h> #include <sys/protosw.h> #include <sys/msgport.h> #include <sys/msgport2.h> #include <sys/thread2.h> #include <sys/socket.h> #include <net/netmsg.h> /* ---------------- DF-2966 ---------------- */ static void dfv66_attach(netmsg_t msg); static struct pr_usrreqs dfv66_usrreqs = { .pru_attach = dfv66_attach, /* every other hook NULL: exactly the pre-net_init_domain state */ }; static struct protosw dfv66_protosw[] = { { .pr_type = SOCK_STREAM, .pr_protocol = 0, .pr_domain = NULL, /* set at fire time */ .pr_usrreqs = &dfv66_usrreqs }, }; static struct protosw dfv66_protosw_end[] = { { .pr_type = 0, .pr_protocol = 0, .pr_domain = NULL, .pr_usrreqs = NULL }, }; #define AF_DFV 99 static struct domain dfv66_domain = { .dom_family = AF_DFV, .dom_name = "dfv66", .dom_protosw = dfv66_protosw, .dom_protoswNPROTOSW = dfv66_protosw_end, }; static void dfv66_attach(netmsg_t msg) { lwkt_replymsg(&msg->lmsg, 0); } static int dfv_d2966(SYSCTL_HANDLER_ARGS) { int error, go = 0; error = sysctl_handle_int(oidp, &go, 0, req); if (error || req->newptr == NULL) return (error); if (go != 1) return (0); dfv66_protosw[0].pr_domain = &dfv66_domain; crit_enter(); SLIST_INSERT_HEAD(&domains, &dfv66_domain, dom_next); crit_exit(); kprintf("DF2966: half-initialized domain AF=%d published (pru_attach " "valid, pru_peeraddr/pru_shutdown/... NULL). Socket() + " "getpeername()/shutdown() now dispatches NULL -> panic.\n", AF_DFV); return (0); } /* ---------------- DF-2907 (panic form) ---------------- */ static int dfv_m2907(SYSCTL_HANDLER_ARGS) { struct mbchain mb; struct mdchain md; struct mbuf *m = NULL; u_char data[64]; int r, error, go = 0; error = sysctl_handle_int(oidp, &go, 0, req); if (error || req->newptr == NULL) return (error); if (go != 1) return (0); memset(data, 0x42, sizeof(data)); mb_init(&mb); mb_put_mem(&mb, data, sizeof(data), MB_MSYSTEM); md_initm(&md, mb_detach(&mb)); kprintf("DF2907P: chain holds 64 bytes; calling md_get_mbuf(128) " "(oversize; md_get_mem return is ignored at :518)\n"); r = md_get_mbuf(&md, 128, &m); /* INVARIANTS: KASSERT in m_copym panics before we get here. non-INVARIANTS: r==0 with a SHORT m -> silent short copy. */ kprintf("DF2907P: md_get_mbuf(128) returned %d m=%p m_len=%d " "(silent success with short mbuf)\n", r, m, m ? m->m_len : -1); if (m) m_freem(m); md_done(&md); return (0); } static SYSCTL_NODE(, OID_AUTO, dfvboom, CTLFLAG_RW, 0, "DF boom rig"); SYSCTL_PROC(_dfvboom, OID_AUTO, d2966, CTLTYPE_INT|CTLFLAG_RW, 0, 0, dfv_d2966, "I", "DF-2966 publish half-init domain"); SYSCTL_PROC(_dfvboom, OID_AUTO, m2907, CTLTYPE_INT|CTLFLAG_RW, 0, 0, dfv_m2907, "I", "DF-2985 oversize md_get_mbuf"); static int dfv_boom_modevent(module_t mod, int type, void *data) { switch (type) { case MOD_LOAD: kprintf("dfv_boom loaded\n"); return (0); case MOD_UNLOAD: return (0); } return (EOPNOTSUPP); } static moduledata_t dfv_boom_mod = { "dfv_boom", dfv_boom_modevent, 0 }; DECLARE_MODULE(dfv_boom, dfv_boom_mod, SI_SUB_DRIVERS, SI_ORDER_ANY); |