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
This commit is contained in:
parent
68d92d47f7
commit
f29d4f3d37
|
@ -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_unit *unit)
|
|||
|
||||
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_unit *unit)
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue