]> xenbits.xensource.com Git - people/liuw/freebsd.git/commitdiff
Fix for unaligned IP-header.
authorhselasky <hselasky@FreeBSD.org>
Fri, 6 Nov 2015 12:54:27 +0000 (12:54 +0000)
committerhselasky <hselasky@FreeBSD.org>
Fri, 6 Nov 2015 12:54:27 +0000 (12:54 +0000)
The mbuf length fields must be set before m_adj() is called else
m_adj() will not always adjust the mbuf and an unaligned read
exception can trigger inside the network stack. This can happen on
platforms where unaligned reads are not supported. Adjust a length
check to include the 2-byte ethernet alignment while at it.

MFC after: 3 days

sys/dev/usb/net/if_cdce.c
sys/dev/usb/net/if_urndis.c

index 13fca9359f2b8b31563212360c87c4ffaedad4ba..397c4f6c779e7247a54f755e9da9b4dba3cccb7f 100644 (file)
@@ -1535,6 +1535,7 @@ cdce_ncm_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
 
                        /* check if we have a buffer */
                        if (m) {
+                               m->m_len = m->m_pkthdr.len = temp + ETHER_ALIGN;
                                m_adj(m, ETHER_ALIGN);
 
                                usbd_copy_out(pc, offset, m->m_data, temp);
index 3c24dcf1d4d75c01f990a6a8abeb222c375321ca..32fa5337094637dac053b9fdb0c3288d3448c056 100644 (file)
@@ -884,7 +884,7 @@ urndis_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
                                DPRINTF("invalid ethernet size "
                                    "%u < %u\n", msg.rm_datalen, (unsigned)sizeof(struct ether_header));
                                goto tr_setup;
-                       } else if (msg.rm_datalen > (uint32_t)MCLBYTES) {
+                       } else if (msg.rm_datalen > (uint32_t)(MCLBYTES - ETHER_ALIGN)) {
                                if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
                                DPRINTF("invalid ethernet size "
                                    "%u > %u\n",
@@ -898,6 +898,7 @@ urndis_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
 
                        /* check if we have a buffer */
                        if (m != NULL) {
+                               m->m_len = m->m_pkthdr.len = msg.rm_datalen + ETHER_ALIGN;
                                m_adj(m, ETHER_ALIGN);
 
                                usbd_copy_out(pc, offset + msg.rm_dataoffset +