Module Name:    src
Committed By:   plunky
Date:           Fri Sep  7 14:47:15 UTC 2018

Modified Files:
        src/sys/netbt: hci_link.c

Log Message:
two issues noted by maxv@

1. If an adaptor sends repeated fragments indicating HCI_PACKET_START,
   we would leak mbufs. Fix that by releasing the previous in that case.

2. If an adaptor sends fragments which overflow the expected total
   payload length, it could build up the pending packet to use up system
   mbufs. Fix that by changing the unsigned calculation to a comparison
   and rejecting oversize packets


To generate a diff of this commit:
cvs rdiff -u -r1.24 -r1.25 src/sys/netbt/hci_link.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netbt/hci_link.c
diff -u src/sys/netbt/hci_link.c:1.24 src/sys/netbt/hci_link.c:1.25
--- src/sys/netbt/hci_link.c:1.24	Tue May 20 18:25:54 2014
+++ src/sys/netbt/hci_link.c	Fri Sep  7 14:47:15 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: hci_link.c,v 1.24 2014/05/20 18:25:54 rmind Exp $	*/
+/*	$NetBSD: hci_link.c,v 1.25 2018/09/07 14:47:15 plunky Exp $	*/
 
 /*-
  * Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hci_link.c,v 1.24 2014/05/20 18:25:54 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hci_link.c,v 1.25 2018/09/07 14:47:15 plunky Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -475,12 +475,15 @@ hci_acl_recv(struct mbuf *m, struct hci_
 
 	switch (pb) {
 	case HCI_PACKET_START:
-		if (link->hl_rxp != NULL)
+		if (m->m_pkthdr.len < sizeof(l2cap_hdr_t))
+			goto bad;
+
+		if (link->hl_rxp != NULL) {
 			aprint_error_dev(unit->hci_dev,
 			    "dropped incomplete ACL packet\n");
 
-		if (m->m_pkthdr.len < sizeof(l2cap_hdr_t))
-			goto bad;
+			m_freem(link->hl_rxp);
+		}
 
 		link->hl_rxp = m;
 		got = m->m_pkthdr.len;
@@ -508,18 +511,24 @@ hci_acl_recv(struct mbuf *m, struct hci_
 	}
 
 	m_copydata(m, 0, sizeof(want), &want);
-	want = le16toh(want) + sizeof(l2cap_hdr_t) - got;
+	want = le16toh(want);
+	got -= sizeof(l2cap_hdr_t);
 
-	if (want > 0)
+	if (got < want)		/* wait for more */
 		return;
 
 	link->hl_rxp = NULL;
 
-	if (want == 0) {
-		l2cap_recv_frame(m, link);
-		return;
+	if (got > want) {
+		DPRINTF("%s: packet overflow\n",
+			device_xname(unit->hci_dev));
+
+		goto bad;
 	}
 
+	l2cap_recv_frame(m, link);
+	return;
+
 bad:
 	m_freem(m);
 }

Reply via email to