DF-0282 / 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 @@ -2407,13 +2407,27 @@ /* Did we get any credits? */ if ((pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) && pf) { + u_int8_t credit; + + /* The credit byte is the first byte of the UIH payload. If the + * frame has no payload, *mtod() reads a stale mbuf byte; require + * at least one byte before consuming it. */ + if (m0->m_pkthdr.len < 1) + goto drop1; + + credit = *mtod(m0, u_int8_t *); NG_BTSOCKET_RFCOMM_INFO( "%s: Got %d more credits for dlci=%d, state=%d, flags=%#x, " \ "rx_cred=%d, tx_cred=%d\n", - __func__, *mtod(m0, u_int8_t *), dlci, pcb->state, + __func__, credit, dlci, pcb->state, pcb->flags, pcb->rx_cred, pcb->tx_cred); - pcb->tx_cred += *mtod(m0, u_int8_t *); + /* tx_cred is int16_t; cap to RFCOMM_MAX_CREDITS to avoid signed + * overflow from many credit-granting UIH frames (CWE-190). */ + if (pcb->tx_cred + credit > RFCOMM_MAX_CREDITS) + pcb->tx_cred = RFCOMM_MAX_CREDITS; + else + pcb->tx_cred += credit; m_adj(m0, 1); /* Send more from the DLC. XXX check for errors? */ |