diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2009-09-13 14:42:53 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2009-09-13 14:42:53 +0000 |
commit | 72c9514b3fe03e2af58b7386b4ea1b1b8d03bb73 (patch) | |
tree | ddd67747f9e94367b396ade568c730dfa795adb5 | |
parent | 4eef650080d9b8f29430c67e8bfb02019d822601 (diff) |
M_DUP_PKTHDR() define -> m_dup_pkthdr() function to properly deal
with m_tag_copy_chain() failures.
Use m_defrag() to eliminate hand rolled defragging of mbufs and
some uses of M_DUP_PKTHDR().
Original diff from thib@, claudio@'s feedback integrated by me.
Tests kevlo@ claudio@, "reads ok" blambert@
ok thib@ claudio@, "m_defrag() bits ok" kettenis@
-rw-r--r-- | sys/dev/ic/acx.c | 32 | ||||
-rw-r--r-- | sys/dev/ic/ath.c | 19 | ||||
-rw-r--r-- | sys/dev/ic/bwi.c | 33 | ||||
-rw-r--r-- | sys/dev/pci/hifn7751.c | 19 | ||||
-rw-r--r-- | sys/dev/pci/if_age.c | 29 | ||||
-rw-r--r-- | sys/dev/pci/if_alc.c | 29 | ||||
-rw-r--r-- | sys/dev/pci/if_ale.c | 29 | ||||
-rw-r--r-- | sys/dev/pci/if_et.c | 31 | ||||
-rw-r--r-- | sys/dev/pci/if_jme.c | 29 | ||||
-rw-r--r-- | sys/dev/pci/safe.c | 11 | ||||
-rw-r--r-- | sys/dev/pci/ubsec.c | 11 | ||||
-rw-r--r-- | sys/kern/uipc_mbuf.c | 35 | ||||
-rw-r--r-- | sys/kern/uipc_mbuf2.c | 11 | ||||
-rw-r--r-- | sys/net80211/ieee80211_crypto_ccmp.c | 12 | ||||
-rw-r--r-- | sys/net80211/ieee80211_crypto_tkip.c | 12 | ||||
-rw-r--r-- | sys/net80211/ieee80211_crypto_wep.c | 12 | ||||
-rw-r--r-- | sys/net80211/ieee80211_input.c | 8 | ||||
-rw-r--r-- | sys/netinet6/icmp6.c | 12 | ||||
-rw-r--r-- | sys/sys/mbuf.h | 17 |
19 files changed, 129 insertions, 262 deletions
diff --git a/sys/dev/ic/acx.c b/sys/dev/ic/acx.c index 693923cbfa3..2f9fe36b098 100644 --- a/sys/dev/ic/acx.c +++ b/sys/dev/ic/acx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acx.c,v 1.94 2009/07/28 11:39:52 blambert Exp $ */ +/* $OpenBSD: acx.c,v 1.95 2009/09/13 14:42:52 krw Exp $ */ /* * Copyright (c) 2006 Jonathan Gray <jsg@openbsd.org> @@ -2222,38 +2222,10 @@ acx_encap(struct acx_softc *sc, struct acx_txbuf *txbuf, struct mbuf *m, if (error) { /* error == EFBIG */ /* too many fragments, linearize */ - struct mbuf *mnew; - - error = 0; - - MGETHDR(mnew, M_DONTWAIT, MT_DATA); - if (mnew == NULL) { - m_freem(m); - error = ENOBUFS; + if (m_defrag(m, M_DONTWAIT)) { printf("%s: can't defrag tx mbuf\n", ifp->if_xname); goto back; } - - M_DUP_PKTHDR(mnew, m); - if (m->m_pkthdr.len > MHLEN) { - MCLGET(mnew, M_DONTWAIT); - if (!(mnew->m_flags & M_EXT)) { - m_freem(m); - m_freem(mnew); - error = ENOBUFS; - } - } - - if (error) { - printf("%s: can't defrag tx mbuf\n", ifp->if_xname); - goto back; - } - - m_copydata(m, 0, m->m_pkthdr.len, mtod(mnew, caddr_t)); - m_freem(m); - mnew->m_len = mnew->m_pkthdr.len; - m = mnew; - error = bus_dmamap_load_mbuf(sc->sc_dmat, txbuf->tb_mbuf_dmamap, m, BUS_DMA_NOWAIT); if (error) { diff --git a/sys/dev/ic/ath.c b/sys/dev/ic/ath.c index 20376840e92..9fbd8940ecb 100644 --- a/sys/dev/ic/ath.c +++ b/sys/dev/ic/ath.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ath.c,v 1.82 2009/08/10 20:29:54 deraadt Exp $ */ +/* $OpenBSD: ath.c,v 1.83 2009/09/13 14:42:52 krw Exp $ */ /* $NetBSD: ath.c,v 1.37 2004/08/18 21:59:39 dyoung Exp $ */ /*- @@ -2135,7 +2135,6 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, int i, error, iswep, hdrlen, pktlen, len, s; u_int8_t rix, cix, txrate, ctsrate; struct ath_desc *ds; - struct mbuf *m; struct ieee80211_frame *wh; struct ieee80211_key *k; u_int32_t iv; @@ -2238,25 +2237,11 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, */ if (error == EFBIG) { /* too many desc's, linearize */ sc->sc_stats.ast_tx_linear++; - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { - sc->sc_stats.ast_tx_nombuf++; - m_freem(m0); - return ENOMEM; - } - - M_DUP_PKTHDR(m, m0); - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { + if (m_defrag(m0, M_DONTWAIT)) { sc->sc_stats.ast_tx_nomcl++; m_freem(m0); - m_free(m); return ENOMEM; } - m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t)); - m_freem(m0); - m->m_len = m->m_pkthdr.len; - m0 = m; error = bus_dmamap_load_mbuf(sc->sc_dmat, bf->bf_dmamap, m0, BUS_DMA_NOWAIT); if (error != 0) { diff --git a/sys/dev/ic/bwi.c b/sys/dev/ic/bwi.c index 027b20d03ff..b4115985ad8 100644 --- a/sys/dev/ic/bwi.c +++ b/sys/dev/ic/bwi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bwi.c,v 1.90 2009/08/02 19:33:01 blambert Exp $ */ +/* $OpenBSD: bwi.c,v 1.91 2009/09/13 14:42:52 krw Exp $ */ /* * Copyright (c) 2007 The DragonFly Project. All rights reserved. @@ -8849,40 +8849,11 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m, } if (error) { /* error == EFBIG */ - struct mbuf *m_new; - - error = 0; - - MGETHDR(m_new, M_DONTWAIT, MT_DATA); - if (m_new == NULL) { - m_freem(m); - error = ENOBUFS; + if (m_defrag(m, M_DONTWAIT)) { printf("%s: can't defrag TX buffer\n", sc->sc_dev.dv_xname); goto back; } - - M_DUP_PKTHDR(m_new, m); - if (m->m_pkthdr.len > MHLEN) { - MCLGET(m_new, M_DONTWAIT); - if (!(m_new->m_flags & M_EXT)) { - m_freem(m); - m_freem(m_new); - error = ENOBUFS; - } - } - - if (error) { - printf("%s: can't defrag TX buffer\n", - sc->sc_dev.dv_xname); - goto back; - } - - m_copydata(m, 0, m->m_pkthdr.len, mtod(m_new, caddr_t)); - m_freem(m); - m_new->m_len = m_new->m_pkthdr.len; - m = m_new; - error = bus_dmamap_load_mbuf(sc->sc_dmat, tb->tb_dmap, m, BUS_DMA_NOWAIT); if (error) { diff --git a/sys/dev/pci/hifn7751.c b/sys/dev/pci/hifn7751.c index eca6ee5a872..660c6be6ef3 100644 --- a/sys/dev/pci/hifn7751.c +++ b/sys/dev/pci/hifn7751.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hifn7751.c,v 1.157 2008/09/25 17:55:28 chl Exp $ */ +/* $OpenBSD: hifn7751.c,v 1.158 2009/09/13 14:42:52 krw Exp $ */ /* * Invertex AEON / Hifn 7751 driver @@ -1429,8 +1429,13 @@ hifn_crypto(struct hifn_softc *sc, struct hifn_command *cmd, err = ENOMEM; goto err_srcmap; } - if (len == MHLEN) - M_DUP_PKTHDR(m0, cmd->srcu.src_m); + if (len == MHLEN) { + err = m_dup_pkthdr(m0, cmd->srcu.src_m); + if (err) { + m_free(m0); + goto err_srcmap; + } + } if (totlen >= MINCLSIZE) { MCLGET(m0, M_DONTWAIT); if (m0->m_flags & M_EXT) @@ -2752,8 +2757,12 @@ hifn_mkmbuf_chain(int totlen, struct mbuf *mtemplate) } if (m0 == NULL) return (NULL); - if (len == MHLEN) - M_DUP_PKTHDR(m0, mtemplate); + if (len == MHLEN) { + if (m_dup_pkthdr(m0, mtemplate)) { + m_free(m0); + return (NULL); + } + } MCLGET(m0, M_DONTWAIT); if (!(m0->m_flags & M_EXT)) m_freem(m0); diff --git a/sys/dev/pci/if_age.c b/sys/dev/pci/if_age.c index 523c8d2d799..a0b51596af4 100644 --- a/sys/dev/pci/if_age.c +++ b/sys/dev/pci/if_age.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_age.c,v 1.6 2009/07/28 13:53:56 kevlo Exp $ */ +/* $OpenBSD: if_age.c,v 1.7 2009/09/13 14:42:52 krw Exp $ */ /*- * Copyright (c) 2008, Pyun YongHyeon <yongari@FreeBSD.org> @@ -1168,43 +1168,18 @@ age_encap(struct age_softc *sc, struct mbuf **m_head) error = EFBIG; } if (error == EFBIG) { - error = 0; - - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { + if (m_defrag(*m_head, M_DONTWAIT)) { printf("%s: can't defrag TX mbuf\n", sc->sc_dev.dv_xname); m_freem(*m_head); *m_head = NULL; return (ENOBUFS); } - - M_DUP_PKTHDR(m, *m_head); - if ((*m_head)->m_pkthdr.len > MHLEN) { - MCLGET(m, M_DONTWAIT); - if (!(m->m_flags & M_EXT)) { - m_freem(*m_head); - m_freem(m); - *m_head = NULL; - return (ENOBUFS); - } - } - m_copydata(*m_head, 0, (*m_head)->m_pkthdr.len, - mtod(m, caddr_t)); - m_freem(*m_head); - m->m_len = m->m_pkthdr.len; - *m_head = m; - error = bus_dmamap_load_mbuf(sc->sc_dmat, map, *m_head, BUS_DMA_NOWAIT); - if (error != 0) { printf("%s: could not load defragged TX mbuf\n", sc->sc_dev.dv_xname); - if (!error) { - bus_dmamap_unload(sc->sc_dmat, map); - error = EFBIG; - } m_freem(*m_head); *m_head = NULL; return (error); diff --git a/sys/dev/pci/if_alc.c b/sys/dev/pci/if_alc.c index 6f36b086e56..d1987c050fd 100644 --- a/sys/dev/pci/if_alc.c +++ b/sys/dev/pci/if_alc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_alc.c,v 1.1 2009/08/08 09:31:13 kevlo Exp $ */ +/* $OpenBSD: if_alc.c,v 1.2 2009/09/13 14:42:52 krw Exp $ */ /*- * Copyright (c) 2009, Pyun YongHyeon <yongari@FreeBSD.org> * All rights reserved. @@ -1024,43 +1024,18 @@ alc_encap(struct alc_softc *sc, struct mbuf **m_head) error = EFBIG; } if (error == EFBIG) { - error = 0; - - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { + if (m_defrag(*m_head, M_DONTWAIT)) { printf("%s: can't defrag TX mbuf\n", sc->sc_dev.dv_xname); m_freem(*m_head); *m_head = NULL; return (ENOBUFS); } - - M_DUP_PKTHDR(m, *m_head); - if ((*m_head)->m_pkthdr.len > MHLEN) { - MCLGET(m, M_DONTWAIT); - if (!(m->m_flags & M_EXT)) { - m_freem(*m_head); - m_freem(m); - *m_head = NULL; - return (ENOBUFS); - } - } - m_copydata(*m_head, 0, (*m_head)->m_pkthdr.len, - mtod(m, caddr_t)); - m_freem(*m_head); - m->m_len = m->m_pkthdr.len; - *m_head = m; - error = bus_dmamap_load_mbuf(sc->sc_dmat, map, *m_head, BUS_DMA_NOWAIT); - if (error != 0) { printf("%s: could not load defragged TX mbuf\n", sc->sc_dev.dv_xname); - if (!error) { - bus_dmamap_unload(sc->sc_dmat, map); - error = EFBIG; - } m_freem(*m_head); *m_head = NULL; return (error); diff --git a/sys/dev/pci/if_ale.c b/sys/dev/pci/if_ale.c index e0f1b11d308..abf811510d1 100644 --- a/sys/dev/pci/if_ale.c +++ b/sys/dev/pci/if_ale.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ale.c,v 1.8 2009/08/09 03:03:19 kevlo Exp $ */ +/* $OpenBSD: if_ale.c,v 1.9 2009/09/13 14:42:52 krw Exp $ */ /*- * Copyright (c) 2008, Pyun YongHyeon <yongari@FreeBSD.org> * All rights reserved. @@ -889,43 +889,18 @@ ale_encap(struct ale_softc *sc, struct mbuf **m_head) error = EFBIG; } if (error == EFBIG) { - error = 0; - - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { + if (m_defrag(*m_head, M_DONTWAIT)) { printf("%s: can't defrag TX mbuf\n", sc->sc_dev.dv_xname); m_freem(*m_head); *m_head = NULL; return (ENOBUFS); } - - M_DUP_PKTHDR(m, *m_head); - if ((*m_head)->m_pkthdr.len > MHLEN) { - MCLGET(m, M_DONTWAIT); - if (!(m->m_flags & M_EXT)) { - m_freem(*m_head); - m_freem(m); - *m_head = NULL; - return (ENOBUFS); - } - } - m_copydata(*m_head, 0, (*m_head)->m_pkthdr.len, - mtod(m, caddr_t)); - m_freem(*m_head); - m->m_len = m->m_pkthdr.len; - *m_head = m; - error = bus_dmamap_load_mbuf(sc->sc_dmat, map, *m_head, BUS_DMA_NOWAIT); - if (error != 0) { printf("%s: could not load defragged TX mbuf\n", sc->sc_dev.dv_xname); - if (!error) { - bus_dmamap_unload(sc->sc_dmat, map); - error = EFBIG; - } m_freem(*m_head); *m_head = NULL; return (error); diff --git a/sys/dev/pci/if_et.c b/sys/dev/pci/if_et.c index 21d630f8c7e..654783c715b 100644 --- a/sys/dev/pci/if_et.c +++ b/sys/dev/pci/if_et.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_et.c,v 1.18 2009/08/10 19:41:05 deraadt Exp $ */ +/* $OpenBSD: if_et.c,v 1.19 2009/09/13 14:42:52 krw Exp $ */ /* * Copyright (c) 2007 The DragonFly Project. All rights reserved. * @@ -1823,40 +1823,13 @@ et_encap(struct et_softc *sc, struct mbuf **m0) goto back; } if (error) { /* error == EFBIG */ - struct mbuf *m_new; - - error = 0; - - MGETHDR(m_new, M_DONTWAIT, MT_DATA); - if (m_new == NULL) { + if (m_defrag(m, M_DONTWAIT)) { m_freem(m); printf("%s: can't defrag TX mbuf\n", sc->sc_dev.dv_xname); error = ENOBUFS; goto back; } - - M_DUP_PKTHDR(m_new, m); - if (m->m_pkthdr.len > MHLEN) { - MCLGET(m_new, M_DONTWAIT); - if (!(m_new->m_flags & M_EXT)) { - m_freem(m); - m_freem(m_new); - error = ENOBUFS; - } - } - - if (error) { - printf("%s: can't defrag TX buffer\n", - sc->sc_dev.dv_xname); - goto back; - } - - m_copydata(m, 0, m->m_pkthdr.len, mtod(m_new, caddr_t)); - m_freem(m); - m_new->m_len = m_new->m_pkthdr.len; - *m0 = m = m_new; - error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT); if (error || map->dm_nsegs == 0) { diff --git a/sys/dev/pci/if_jme.c b/sys/dev/pci/if_jme.c index 08ef0fee257..57a2d3a7765 100644 --- a/sys/dev/pci/if_jme.c +++ b/sys/dev/pci/if_jme.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_jme.c,v 1.19 2009/06/05 06:05:06 naddy Exp $ */ +/* $OpenBSD: if_jme.c,v 1.20 2009/09/13 14:42:52 krw Exp $ */ /*- * Copyright (c) 2008, Pyun YongHyeon <yongari@FreeBSD.org> * All rights reserved. @@ -1084,44 +1084,19 @@ jme_encap(struct jme_softc *sc, struct mbuf **m_head) error = EFBIG; } if (error == EFBIG) { - error = 0; - - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { + if (m_defrag(*m_head, M_DONTWAIT)) { printf("%s: can't defrag TX mbuf\n", sc->sc_dev.dv_xname); m_freem(*m_head); *m_head = NULL; return (ENOBUFS); } - - M_DUP_PKTHDR(m, *m_head); - if ((*m_head)->m_pkthdr.len > MHLEN) { - MCLGET(m, M_DONTWAIT); - if (!(m->m_flags & M_EXT)) { - m_freem(*m_head); - m_freem(m); - *m_head = NULL; - return (ENOBUFS); - } - } - - m_copydata(*m_head, 0, (*m_head)->m_pkthdr.len, mtod(m, caddr_t)); - m_freem(*m_head); - m->m_len = m->m_pkthdr.len; - *m_head = m; - error = bus_dmamap_load_mbuf(sc->sc_dmat, txd->tx_dmamap, *m_head, BUS_DMA_NOWAIT); if (error != 0) { printf("%s: could not load defragged TX mbuf\n", sc->sc_dev.dv_xname); - if (!error) { - bus_dmamap_unload(sc->sc_dmat, - txd->tx_dmamap); - error = EFBIG; - } m_freem(*m_head); *m_head = NULL; return (error); diff --git a/sys/dev/pci/safe.c b/sys/dev/pci/safe.c index afcaca04708..62fff55053c 100644 --- a/sys/dev/pci/safe.c +++ b/sys/dev/pci/safe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: safe.c,v 1.25 2009/06/25 10:14:48 jsg Exp $ */ +/* $OpenBSD: safe.c,v 1.26 2009/09/13 14:42:52 krw Exp $ */ /*- * Copyright (c) 2003 Sam Leffler, Errno Consulting @@ -806,8 +806,13 @@ safe_process(struct cryptop *crp) err = sc->sc_nqchip ? ERESTART : ENOMEM; goto errout; } - if (len == MHLEN) - M_DUP_PKTHDR(m, re->re_src_m); + if (len == MHLEN) { + err = m_dup_pkthdr(m, re->re_src_m); + if (err) { + m_free(m); + goto errout; + } + } if (totlen >= MINCLSIZE) { MCLGET(m, M_DONTWAIT); if ((m->m_flags & M_EXT) == 0) { diff --git a/sys/dev/pci/ubsec.c b/sys/dev/pci/ubsec.c index a53469ce500..08ab6c98db9 100644 --- a/sys/dev/pci/ubsec.c +++ b/sys/dev/pci/ubsec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ubsec.c,v 1.143 2009/03/27 13:31:30 reyk Exp $ */ +/* $OpenBSD: ubsec.c,v 1.144 2009/09/13 14:42:52 krw Exp $ */ /* * Copyright (c) 2000 Jason L. Wright (jason@thought.net) @@ -1159,8 +1159,13 @@ ubsec_process(struct cryptop *crp) err = ENOMEM; goto errout; } - if (len == MHLEN) - M_DUP_PKTHDR(m, q->q_src_m); + if (len == MHLEN) { + err = m_dup_pkthdr(m, q->q_src_m); + if (err) { + m_freem(m); + goto errout; + } + } if (totlen >= MINCLSIZE) { MCLGET(m, M_DONTWAIT); if (m->m_flags & M_EXT) diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 96c3b2da5c5..9c9cae4d301 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_mbuf.c,v 1.133 2009/08/12 21:44:49 henning Exp $ */ +/* $OpenBSD: uipc_mbuf.c,v 1.134 2009/09/13 14:42:52 krw Exp $ */ /* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */ /* @@ -629,7 +629,8 @@ m_copym0(struct mbuf *m, int off, int len, int wait, int deep) if (n == NULL) goto nospace; if (copyhdr) { - M_DUP_PKTHDR(n, m); + if (m_dup_pkthdr(n, m)) + goto nospace; if (len != M_COPYALL) n->m_pkthdr.len = len; copyhdr = 0; @@ -1124,7 +1125,10 @@ m_split(struct mbuf *m0, int len0, int wait) MGETHDR(n, wait, m0->m_type); if (n == NULL) return (NULL); - M_DUP_PKTHDR(n, m0); + if (m_dup_pkthdr(n, m0)) { + m_freem(n); + return (NULL); + } n->m_pkthdr.len -= len0; olen = m0->m_pkthdr.len; m0->m_pkthdr.len = len0; @@ -1315,3 +1319,28 @@ m_trailingspace(struct mbuf *m) m->m_ext.ext_size - (m->m_data + m->m_len) : &m->m_dat[MLEN] - (m->m_data + m->m_len)); } + + +/* + * Duplicate mbuf pkthdr from from to to. + * from must have M_PKTHDR set, and to must be empty. + */ +int +m_dup_pkthdr(struct mbuf *to, struct mbuf *from) +{ + KASSERT(from->m_flags & M_PKTHDR); + + to->m_flags = (to->m_flags & (M_EXT | M_CLUSTER)); + to->m_flags |= (from->m_flags & M_COPYFLAGS); + to->m_pkthdr = from->m_pkthdr; + + SLIST_INIT(&to->m_pkthdr.tags); + + if (m_tag_copy_chain(to, from)) + return (ENOMEM); + + if ((to->m_flags & M_EXT) == 0) + to->m_data = to->m_pktdat; + + return (0); +} diff --git a/sys/kern/uipc_mbuf2.c b/sys/kern/uipc_mbuf2.c index 11b45a64d20..f6d1407a844 100644 --- a/sys/kern/uipc_mbuf2.c +++ b/sys/kern/uipc_mbuf2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_mbuf2.c,v 1.30 2009/08/09 12:50:09 henning Exp $ */ +/* $OpenBSD: uipc_mbuf2.c,v 1.31 2009/09/13 14:42:52 krw Exp $ */ /* $KAME: uipc_mbuf2.c,v 1.29 2001/02/14 13:42:10 itojun Exp $ */ /* $NetBSD: uipc_mbuf.c,v 1.40 1999/04/01 00:23:25 thorpej Exp $ */ @@ -233,7 +233,10 @@ m_dup1(struct mbuf *m, int off, int len, int wait) MGETHDR(n, wait, m->m_type); if (n == NULL) return (NULL); - M_DUP_PKTHDR(n, m); + if (m_dup_pkthdr(n, m)) { + m_free(n); + return (NULL); + } l = MHLEN; } else { MGET(n, wait, m->m_type); @@ -358,7 +361,7 @@ m_tag_copy_chain(struct mbuf *to, struct mbuf *from) t = m_tag_copy(p); if (t == NULL) { m_tag_delete_chain(to); - return (0); + return (1); } if (tprev == NULL) SLIST_INSERT_HEAD(&to->m_pkthdr.tags, t, m_tag_link); @@ -367,7 +370,7 @@ m_tag_copy_chain(struct mbuf *to, struct mbuf *from) tprev = t; to->m_pkthdr.tagsset |= t->m_tag_id; } - return (1); + return (0); } /* Initialize tags on an mbuf. */ diff --git a/sys/net80211/ieee80211_crypto_ccmp.c b/sys/net80211/ieee80211_crypto_ccmp.c index b3f15adb054..728a363c25b 100644 --- a/sys/net80211/ieee80211_crypto_ccmp.c +++ b/sys/net80211/ieee80211_crypto_ccmp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_crypto_ccmp.c,v 1.8 2008/12/03 17:25:41 damien Exp $ */ +/* $OpenBSD: ieee80211_crypto_ccmp.c,v 1.9 2009/09/13 14:42:52 krw Exp $ */ /*- * Copyright (c) 2008 Damien Bergamini <damien.bergamini@free.fr> @@ -176,7 +176,10 @@ ieee80211_ccmp_encrypt(struct ieee80211com *ic, struct mbuf *m0, MGET(n0, M_DONTWAIT, m0->m_type); if (n0 == NULL) goto nospace; - M_DUP_PKTHDR(n0, m0); + if (m_dup_pkthdr(n0, m0)) { + m_free(n0); + goto nospace; + } n0->m_pkthdr.len += IEEE80211_CCMP_HDRLEN; n0->m_len = MHLEN; if (n0->m_pkthdr.len >= MINCLSIZE - IEEE80211_CCMP_MICLEN) { @@ -354,7 +357,10 @@ ieee80211_ccmp_decrypt(struct ieee80211com *ic, struct mbuf *m0, MGET(n0, M_DONTWAIT, m0->m_type); if (n0 == NULL) goto nospace; - M_DUP_PKTHDR(n0, m0); + if (m_dup_pkthdr(n0, m0)) { + m_free(n0); + goto nospace; + } n0->m_pkthdr.len -= IEEE80211_CCMP_HDRLEN + IEEE80211_CCMP_MICLEN; n0->m_len = MHLEN; if (n0->m_pkthdr.len >= MINCLSIZE) { diff --git a/sys/net80211/ieee80211_crypto_tkip.c b/sys/net80211/ieee80211_crypto_tkip.c index a78adb5ae36..38574e00abb 100644 --- a/sys/net80211/ieee80211_crypto_tkip.c +++ b/sys/net80211/ieee80211_crypto_tkip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_crypto_tkip.c,v 1.14 2009/04/16 18:32:24 damien Exp $ */ +/* $OpenBSD: ieee80211_crypto_tkip.c,v 1.15 2009/09/13 14:42:52 krw Exp $ */ /*- * Copyright (c) 2008 Damien Bergamini <damien.bergamini@free.fr> @@ -198,7 +198,10 @@ ieee80211_tkip_encrypt(struct ieee80211com *ic, struct mbuf *m0, MGET(n0, M_DONTWAIT, m0->m_type); if (n0 == NULL) goto nospace; - M_DUP_PKTHDR(n0, m0); + if (m_dup_pkthdr(n0, m0)) { + m_free(n0); + goto nospace; + } n0->m_pkthdr.len += IEEE80211_TKIP_HDRLEN; n0->m_len = MHLEN; if (n0->m_pkthdr.len >= MINCLSIZE - IEEE80211_TKIP_TAILLEN) { @@ -367,7 +370,10 @@ ieee80211_tkip_decrypt(struct ieee80211com *ic, struct mbuf *m0, MGET(n0, M_DONTWAIT, m0->m_type); if (n0 == NULL) goto nospace; - M_DUP_PKTHDR(n0, m0); + if (m_dup_pkthdr(n0, m0)) { + m_free(n0); + goto nospace; + } n0->m_pkthdr.len -= IEEE80211_TKIP_OVHD; n0->m_len = MHLEN; if (n0->m_pkthdr.len >= MINCLSIZE) { diff --git a/sys/net80211/ieee80211_crypto_wep.c b/sys/net80211/ieee80211_crypto_wep.c index ccd08067f4a..6ca41735647 100644 --- a/sys/net80211/ieee80211_crypto_wep.c +++ b/sys/net80211/ieee80211_crypto_wep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_crypto_wep.c,v 1.5 2008/08/12 16:45:44 damien Exp $ */ +/* $OpenBSD: ieee80211_crypto_wep.c,v 1.6 2009/09/13 14:42:52 krw Exp $ */ /*- * Copyright (c) 2008 Damien Bergamini <damien.bergamini@free.fr> @@ -95,7 +95,10 @@ ieee80211_wep_encrypt(struct ieee80211com *ic, struct mbuf *m0, MGET(n0, M_DONTWAIT, m0->m_type); if (n0 == NULL) goto nospace; - M_DUP_PKTHDR(n0, m0); + if (m_dup_pkthdr(n0, m0)) { + m_free(n0); + goto nospace; + } n0->m_pkthdr.len += IEEE80211_WEP_HDRLEN; n0->m_len = MHLEN; if (n0->m_pkthdr.len >= MINCLSIZE - IEEE80211_WEP_CRCLEN) { @@ -227,7 +230,10 @@ ieee80211_wep_decrypt(struct ieee80211com *ic, struct mbuf *m0, MGET(n0, M_DONTWAIT, m0->m_type); if (n0 == NULL) goto nospace; - M_DUP_PKTHDR(n0, m0); + if (m_dup_pkthdr(n0, m0)) { + m_free(n0); + goto nospace; + } n0->m_pkthdr.len -= IEEE80211_WEP_TOTLEN; n0->m_len = MHLEN; if (n0->m_pkthdr.len >= MINCLSIZE) { diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c index 6e8e0aae021..0c49a60eb05 100644 --- a/sys/net80211/ieee80211_input.c +++ b/sys/net80211/ieee80211_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_input.c,v 1.111 2009/03/26 20:34:54 damien Exp $ */ +/* $OpenBSD: ieee80211_input.c,v 1.112 2009/09/13 14:42:52 krw Exp $ */ /*- * Copyright (c) 2001 Atsushi Onoe @@ -861,7 +861,11 @@ ieee80211_align_mbuf(struct mbuf *m) m_freem(m); return NULL; } - M_DUP_PKTHDR(n, m); + if (m_dup_pkthdr(n, m)) { + m_free(n); + m_freem(m); + return (NULL); + } n->m_len = MHLEN; } else { MGET(n, M_DONTWAIT, MT_DATA); diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 15fbdc608ce..164b202af74 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: icmp6.c,v 1.106 2009/07/26 12:59:17 thib Exp $ */ +/* $OpenBSD: icmp6.c,v 1.107 2009/09/13 14:42:52 krw Exp $ */ /* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */ /* @@ -742,7 +742,10 @@ icmp6_input(struct mbuf **mp, int *offp, int proto) bzero(p, 4); bcopy(hostname, p + 4, maxhlen); /* meaningless TTL */ noff = sizeof(struct ip6_hdr); - M_DUP_PKTHDR(n, m); /* just for rcvif */ + if (m_dup_pkthdr(n, m)) { /* just for rcvif */ + m_freem(n); + break; + } n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr) + 4 + maxhlen; nicmp6->icmp6_type = ICMP6_WRUREPLY; @@ -1383,7 +1386,10 @@ ni6_input(struct mbuf *m, int off) m_freem(m); return (NULL); } - M_DUP_PKTHDR(n, m); /* just for rcvif */ + + if (m_dup_pkthdr(n, m)) /* just for rcvif */ + goto bad; + if (replylen > MHLEN) { if (replylen > MCLBYTES) { /* diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index 00f5295cb90..09572fc3540 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mbuf.h,v 1.135 2009/09/08 17:52:18 michele Exp $ */ +/* $OpenBSD: mbuf.h,v 1.136 2009/09/13 14:42:52 krw Exp $ */ /* $NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $ */ /* @@ -290,20 +290,6 @@ struct mbuf { } while (/* CONSTCOND */ 0) /* - * Duplicate mbuf pkthdr from from to to. - * from must have M_PKTHDR set, and to must be empty. - */ -#define M_DUP_PKTHDR(to, from) do { \ - (to)->m_flags = ((to)->m_flags & (M_EXT | M_CLUSTER)); \ - (to)->m_flags |= (from)->m_flags & M_COPYFLAGS; \ - (to)->m_pkthdr = (from)->m_pkthdr; \ - SLIST_INIT(&(to)->m_pkthdr.tags); \ - m_tag_copy_chain((to), (from)); \ - if (((to)->m_flags & M_EXT) == 0) \ - (to)->m_data = (to)->m_pktdat; \ -} while (/* CONSTCOND */ 0) - -/* * MOVE mbuf pkthdr from from to to. * from must have M_PKTHDR set, and to must be empty. */ @@ -433,6 +419,7 @@ struct mbuf *m_devget(char *, int, int, struct ifnet *, void m_zero(struct mbuf *); int m_apply(struct mbuf *, int, int, int (*)(caddr_t, caddr_t, unsigned int), caddr_t); +int m_dup_pkthdr(struct mbuf *, struct mbuf *); /* Packet tag routines */ struct m_tag *m_tag_get(int, int, int); |