diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2019-01-22 18:06:06 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2019-01-22 18:06:06 +0000 |
commit | a6c5dd3bfdea1d7f141a3628b81326726730e664 (patch) | |
tree | 70066e495480e62dcb7236d8123964c721bee988 /sys/dev/usb/if_urndis.c | |
parent | 63e466c809dc8e01d306b2464498b085f1319856 (diff) |
Do not leak received mbufs if the NDIS appended a zero-byte padding.
from aalm@
Diffstat (limited to 'sys/dev/usb/if_urndis.c')
-rw-r--r-- | sys/dev/usb/if_urndis.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/sys/dev/usb/if_urndis.c b/sys/dev/usb/if_urndis.c index f6b3c7bad9d..8700fc6eb49 100644 --- a/sys/dev/usb/if_urndis.c +++ b/sys/dev/usb/if_urndis.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_urndis.c,v 1.68 2018/10/02 19:49:10 stsp Exp $ */ +/* $OpenBSD: if_urndis.c,v 1.69 2019/01/22 18:06:05 mpi Exp $ */ /* * Copyright (c) 2010 Jonathan Armani <armani@openbsd.org> @@ -826,7 +826,7 @@ urndis_decap(struct urndis_softc *sc, struct urndis_chain *c, u_int32_t len) ifp = GET_IFP(sc); offset = 0; - while (len > 0) { + while (len > 1) { msg = (struct rndis_packet_msg *)((char*)c->sc_buf + offset); m = c->sc_mbuf; @@ -839,7 +839,7 @@ urndis_decap(struct urndis_softc *sc, struct urndis_chain *c, u_int32_t len) DEVNAME(sc), len, sizeof(*msg)); - return; + break; } DPRINTF(("%s: urndis_decap len %u data(off:%u len:%u) " @@ -859,14 +859,14 @@ urndis_decap(struct urndis_softc *sc, struct urndis_chain *c, u_int32_t len) DEVNAME(sc), letoh32(msg->rm_type), REMOTE_NDIS_PACKET_MSG); - return; + break; } if (letoh32(msg->rm_len) < sizeof(*msg)) { printf("%s: urndis_decap invalid msg len %u < %zu\n", DEVNAME(sc), letoh32(msg->rm_len), sizeof(*msg)); - return; + break; } if (letoh32(msg->rm_len) > len) { printf("%s: urndis_decap invalid msg len %u > buffer " @@ -874,7 +874,7 @@ urndis_decap(struct urndis_softc *sc, struct urndis_chain *c, u_int32_t len) DEVNAME(sc), letoh32(msg->rm_len), len); - return; + break; } if (letoh32(msg->rm_dataoffset) + @@ -889,7 +889,7 @@ urndis_decap(struct urndis_softc *sc, struct urndis_chain *c, u_int32_t len) letoh32(msg->rm_dataoffset) + letoh32(msg->rm_datalen) + RNDIS_HEADER_OFFSET, letoh32(msg->rm_len)); - return; + break; } if (letoh32(msg->rm_datalen) < sizeof(struct ether_header)) { @@ -899,7 +899,7 @@ urndis_decap(struct urndis_softc *sc, struct urndis_chain *c, u_int32_t len) DEVNAME(sc), letoh32(msg->rm_datalen), sizeof(struct ether_header))); - return; + break; } memcpy(mtod(m, char*), @@ -916,6 +916,8 @@ urndis_decap(struct urndis_softc *sc, struct urndis_chain *c, u_int32_t len) offset += letoh32(msg->rm_len); len -= letoh32(msg->rm_len); } + if (ml_empty(&ml)) + return; s = splnet(); if_input(ifp, &ml); |