Index: if_vr.c =================================================================== RCS file: /home/ncvs/src/sys/pci/if_vr.c,v retrieving revision 1.126 diff -u -r1.126 if_vr.c --- if_vr.c 23 Apr 2007 12:19:02 -0000 1.126 +++ if_vr.c 8 Oct 2007 06:14:41 -0000 @@ -1217,6 +1217,7 @@ struct vr_desc *cur_tx, *n_tx; struct vr_desc *f = NULL; uint32_t cval; + int padlen; if (ifp->if_drv_flags & IFF_DRV_OACTIVE) return; @@ -1250,11 +1251,33 @@ * ourselves. */ if (m_head->m_pkthdr.len < VR_MIN_FRAMELEN) { - if (m_head->m_next != NULL) - m_head = m_defrag(m_head, M_DONTWAIT); - m_head->m_pkthdr.len += VR_MIN_FRAMELEN - m_head->m_len; + padlen = VR_MIN_FRAMELEN - m_head->m_pkthdr.len; + if (M_WRITABLE(m_head) == 0) { + m = m_dup(m_head, M_DONTWAIT); + if (m == NULL) { + IFQ_DRV_PREPEND(&ifp->if_snd, m_head); + break; + } + m_freem(m_head); + m_head = m; + } + if (m_head->m_next != NULL || + M_TRAILINGSPACE(m_head) < padlen) { + m = m_defrag(m_head, M_DONTWAIT); + if (m == NULL) { + IFQ_DRV_PREPEND(&ifp->if_snd, m_head); + break; + } + m_head = m; + } + /* + * Manually pad short frames, and zero the pad space + * to avoid leaking data. + */ + bzero(mtod(m_head, char *) + m_head->m_pkthdr.len, + padlen); + m_head->m_pkthdr.len += padlen; m_head->m_len = m_head->m_pkthdr.len; - /* XXX: bzero the padding bytes */ } n_tx = cur_tx;