summaryrefslogtreecommitdiffstats
path: root/sys/netgraph/ng_cisco.c
diff options
context:
space:
mode:
authorarchie <archie@FreeBSD.org>2002-06-05 23:29:29 +0000
committerarchie <archie@FreeBSD.org>2002-06-05 23:29:29 +0000
commit40b64d10d776065e68625944c67fdaa006c8cfa9 (patch)
treef9a238e01e472bfde0491aeb7402d9bab587e2cc /sys/netgraph/ng_cisco.c
parent2971698c460fdf99fe11db08cb7a88a0aff6d8f1 (diff)
downloadFreeBSD-src-40b64d10d776065e68625944c67fdaa006c8cfa9.zip
FreeBSD-src-40b64d10d776065e68625944c67fdaa006c8cfa9.tar.gz
Fix bugs where mbuf data was being accessed without m_pullup().
Reviewed by: julian, brian MFC after: 1 week
Diffstat (limited to 'sys/netgraph/ng_cisco.c')
-rw-r--r--sys/netgraph/ng_cisco.c50
1 files changed, 43 insertions, 7 deletions
diff --git a/sys/netgraph/ng_cisco.c b/sys/netgraph/ng_cisco.c
index 583f7ac..13d5dd3 100644
--- a/sys/netgraph/ng_cisco.c
+++ b/sys/netgraph/ng_cisco.c
@@ -443,20 +443,31 @@ cisco_disconnect(hook_p hook)
static int
cisco_input(sc_p sc, item_p item)
{
- struct cisco_header *h;
- struct cisco_packet *p;
+ const struct cisco_header *h;
+ struct cisco_header hdrbuf;
struct protoent *pep;
int error = 0;
struct mbuf *m;
+ /* Get data */
m = NGI_M(item);
- if (m->m_pkthdr.len <= CISCO_HEADER_LEN)
+
+ /* Sanity check header length */
+ if (m->m_pkthdr.len < sizeof(*h)) {
+ error = EINVAL;
goto drop;
+ }
- /* Strip off cisco header */
- h = mtod(m, struct cisco_header *);
- m_adj(m, CISCO_HEADER_LEN);
+ /* Get cisco header */
+ if (m->m_len >= sizeof(*h)) /* the common case */
+ h = mtod(m, const struct cisco_header *);
+ else {
+ m_copydata(m, 0, sizeof(*h), (caddr_t)&hdrbuf);
+ h = &hdrbuf;
+ }
+ m_adj(m, sizeof(*h));
+ /* Check header address */
switch (h->address) {
default: /* Invalid Cisco packet. */
goto drop;
@@ -467,7 +478,25 @@ cisco_input(sc_p sc, item_p item)
default:
goto drop;
case CISCO_KEEPALIVE:
- p = mtod(m, struct cisco_packet *);
+ {
+ const struct cisco_packet *p;
+ struct cisco_packet pktbuf;
+
+ /* Sanity check packet length */
+ if (m->m_pkthdr.len < sizeof(*p)) {
+ error = EINVAL;
+ goto drop;
+ }
+
+ /* Get cisco packet */
+ if (m->m_len >= sizeof(*p)) /* the common case */
+ p = mtod(m, const struct cisco_packet *);
+ else {
+ m_copydata(m, 0, sizeof(*p), (caddr_t)&pktbuf);
+ p = &pktbuf;
+ }
+
+ /* Check packet type */
switch (ntohl(p->type)) {
default:
log(LOG_WARNING,
@@ -512,6 +541,7 @@ cisco_input(sc_p sc, item_p item)
}
}
goto drop;
+ }
case ETHERTYPE_IP:
pep = &sc->inet;
break;
@@ -528,6 +558,12 @@ cisco_input(sc_p sc, item_p item)
break;
}
+ /* Drop if payload is empty */
+ if (m->m_pkthdr.len == 0) {
+ error = EINVAL;
+ goto drop;
+ }
+
/* Send it on */
if (pep->hook == NULL)
goto drop;
OpenPOWER on IntegriCloud