Index: bpf.c =================================================================== RCS file: /cvs/src/sys/net/bpf.c,v retrieving revision 1.210 diff -u -p -r1.210 bpf.c --- bpf.c 16 Jan 2022 06:27:14 -0000 1.210 +++ bpf.c 3 Feb 2022 12:21:33 -0000 @@ -144,7 +144,7 @@ bpf_movein(struct uio *uio, struct bpf_d struct mbuf *m; struct m_tag *mtag; int error; - u_int hlen; + u_int hlen, alen, mlen; u_int len; u_int linktype; u_int slen; @@ -198,23 +198,38 @@ bpf_movein(struct uio *uio, struct bpf_d return (EIO); } - if (uio->uio_resid > MAXMCLBYTES) - return (EIO); len = uio->uio_resid; + if (len < hlen) + return (EPERM); - MGETHDR(m, M_WAIT, MT_DATA); - m->m_pkthdr.ph_ifidx = 0; - m->m_pkthdr.len = len - hlen; + /* + * Get the length of the payload so we can align it properly. + */ + alen = len - hlen; + + /* + * Allocate enough space for headers and the aligned payload. + */ + mlen = max(max_linkhdr, hlen) + roundup(alen, sizeof(long)); + + if (mlen > MAXMCLBYTES) + return (EIO); - if (len > MHLEN) { - MCLGETL(m, M_WAIT, len); + MGETHDR(m, M_WAIT, MT_DATA); + if (mlen > MHLEN) { + MCLGETL(m, M_WAIT, mlen); if ((m->m_flags & M_EXT) == 0) { error = ENOBUFS; goto bad; } } + + m_align(m, alen); /* Align the payload. */ + m->m_data -= hlen; + + m->m_pkthdr.ph_ifidx = 0; + m->m_pkthdr.len = len; m->m_len = len; - *mp = m; error = uiomove(mtod(m, caddr_t), len, uio); if (error) @@ -232,10 +247,6 @@ bpf_movein(struct uio *uio, struct bpf_d goto bad; } - if (m->m_len < hlen) { - error = EPERM; - goto bad; - } /* * Make room for link header, and copy it to sockaddr */ @@ -249,8 +260,10 @@ bpf_movein(struct uio *uio, struct bpf_d sockp->sa_family = ntohl(af); } else memcpy(sockp->sa_data, m->m_data, hlen); + + m->m_pkthdr.len -= hlen; m->m_len -= hlen; - m->m_data += hlen; /* XXX */ + m->m_data += hlen; } /* @@ -260,6 +273,7 @@ bpf_movein(struct uio *uio, struct bpf_d *(u_int *)(mtag + 1) = linktype; m_tag_prepend(m, mtag); + *mp = m; return (0); bad: m_freem(m);