diff options
author | hselasky <hselasky@FreeBSD.org> | 2015-11-06 12:54:27 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2015-11-06 12:54:27 +0000 |
commit | 8073a934f24b99ee699265813b908f81511183ab (patch) | |
tree | 1a19ac0e71f2c0171812343d83766fe070b11716 | |
parent | 9637753d1aaf4df5d135f6885f2795338bec7cbc (diff) | |
download | FreeBSD-src-8073a934f24b99ee699265813b908f81511183ab.zip FreeBSD-src-8073a934f24b99ee699265813b908f81511183ab.tar.gz |
Fix for unaligned IP-header.
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
-rw-r--r-- | sys/dev/usb/net/if_cdce.c | 1 | ||||
-rw-r--r-- | sys/dev/usb/net/if_urndis.c | 3 |
2 files changed, 3 insertions, 1 deletions
diff --git a/sys/dev/usb/net/if_cdce.c b/sys/dev/usb/net/if_cdce.c index 13fca93..397c4f6 100644 --- a/sys/dev/usb/net/if_cdce.c +++ b/sys/dev/usb/net/if_cdce.c @@ -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); diff --git a/sys/dev/usb/net/if_urndis.c b/sys/dev/usb/net/if_urndis.c index 3c24dcf..32fa533 100644 --- a/sys/dev/usb/net/if_urndis.c +++ b/sys/dev/usb/net/if_urndis.c @@ -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 + |