⬢ DragonFlyBSD Kernel Audit
DF-5742 / fix.diff
← back to finding ↓ download raw
--- a/sys/netbt/hci_socket.c
+++ b/sys/netbt/hci_socket.c
@@ -1001,7 +1001,23 @@
 		 * copy to socket
 		 */
 		m0 = m_copym(m, 0, M_COPYALL, M_NOWAIT);
-		if (m0 && sbappendaddr(&pcb->hp_socket->so_rcv.sb,
+		/*
+		 * Fix (DF-5742): do not tap into sockets whose receive
+		 * buffer is full -- sbappendaddr() enforces no limit, so
+		 * a non-reading tap socket would otherwise accumulate
+		 * mbufs without bound and drain the global mbuf pool.
+		 */
+		if (m0 == NULL) {
+			m_freem(ctlmsg);
+			continue;
+		}
+		if (ssb_space(&pcb->hp_socket->so_rcv) < m0->m_pkthdr.len &&
+		    (pcb->hp_socket->so_rcv.ssb_flags & SSB_NOINTR) == 0) {
+			m_freem(ctlmsg);
+			m_freem(m0);
+			continue;
+		}
+		if (sbappendaddr(&pcb->hp_socket->so_rcv.sb,
 				(struct sockaddr *)&sa, m0, ctlmsg)) {
 			sorwakeup(pcb->hp_socket);
 		} else {