From 24c418a7ad7240143671f41d2db2093f93a64da0 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sun, 2 May 2021 19:56:54 +0200 Subject: if_wg: ensure packet is not shared before writing Signed-off-by: Jason A. Donenfeld --- src/if_wg.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/if_wg.c b/src/if_wg.c index a373958..465b493 100644 --- a/src/if_wg.c +++ b/src/if_wg.c @@ -1965,6 +1965,11 @@ wg_input(struct mbuf *m, int offset, struct inpcb *inpcb, defragged = m_defrag(m, M_NOWAIT); if (defragged) m = defragged; + m = m_unshare(m, M_NOWAIT); + if (!m) { + if_inc_counter(sc->sc_ifp, IFCOUNTER_IQDROPS, 1); + return; + } /* Caller provided us with `sa`, no need for this header. */ m_adj(m, offset + sizeof(struct udphdr)); @@ -2087,7 +2092,7 @@ xmit_err(struct ifnet *ifp, struct mbuf *m, struct wg_packet *pkt, sa_family_t a } if (pkt) wg_packet_free(pkt); - else + else if (m) m_freem(m); } @@ -2187,6 +2192,11 @@ wg_transmit(struct ifnet *ifp, struct mbuf *m) defragged = m_defrag(m, M_NOWAIT); if (defragged) m = defragged; + m = m_unshare(m, M_NOWAIT); + if (!m) { + xmit_err(ifp, m, NULL, AF_UNSPEC); + return (ENOBUFS); + } ret = determine_af_and_pullup(&m, &af); if (ret) { @@ -2216,6 +2226,11 @@ wg_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, struct defragged = m_defrag(m, M_NOWAIT); if (defragged) m = defragged; + m = m_unshare(m, M_NOWAIT); + if (!m) { + xmit_err(ifp, m, NULL, AF_UNSPEC); + return (ENOBUFS); + } ret = determine_af_and_pullup(&m, &parsed_af); if (ret) { -- cgit v1.2.3-59-g8ed1b