DF-0281 / fix.diff
diff --git a/sys/netgraph7/bluetooth/socket/ng_btsocket_rfcomm.c b/sys/netgraph7/bluetooth/socket/ng_btsocket_rfcomm.c --- a/sys/netgraph7/bluetooth/socket/ng_btsocket_rfcomm.c +++ b/sys/netgraph7/bluetooth/socket/ng_btsocket_rfcomm.c @@ -3016,7 +3016,11 @@ { KKASSERT(lockowned(&pcb->pcb_lock) != 0); - pcb->mtu = le16toh(mtu); + /* DF-0281: the peer controls this value via a PN MCC frame; a zero + * MTU later reaches an unguarded divisor in + * ng_btsocket_rfcomm_send_credits() (line 3283). Reject/replace + * an invalid (zero) MTU instead of trusting the peer. */ + pcb->mtu = (le16toh(mtu) != 0) ? le16toh(mtu) : RFCOMM_DEFAULT_MTU; if (cr) { if (flow_control == 0xf0) { @@ -3280,6 +3284,11 @@ __func__, pcb->dlci, pcb->state, pcb->flags, pcb->mtu, ssb_space(&pcb->so->so_rcv), pcb->tx_cred, pcb->rx_cred); + /* DF-0281: never divide by pcb->mtu even if an earlier writer left + * it zero; bail out instead of faulting (#DE -> kernel panic). */ + if (pcb->mtu == 0) + return (EINVAL); + credits = ssb_space(&pcb->so->so_rcv) / pcb->mtu; if (credits > 0) { if (pcb->rx_cred + credits > RFCOMM_MAX_CREDITS) |