From e63ce21b1a1a572f6fe1103d7e322494f5180211 Mon Sep 17 00:00:00 2001 From: bluhm Date: Sun, 24 Oct 2021 17:08:27 +0000 Subject: [PATCH] There are more m_pullup() in IPsec input. Pass down the pointer to the mbuf to update it globally. At the end it will reach ip_deliver() which expects a pointer to an mbuf. OK sashan@ --- sys/netinet/ip_ah.c | 11 ++++++----- sys/netinet/ip_esp.c | 13 +++++++------ sys/netinet/ip_ipcomp.c | 15 +++++++++------ sys/netinet/ip_ipsp.h | 11 ++++++----- sys/netinet/ipsec_input.c | 14 ++++++++------ 5 files changed, 36 insertions(+), 28 deletions(-) diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c index 23ea3ffb12a..40347ee61b9 100644 --- a/sys/netinet/ip_ah.c +++ b/sys/netinet/ip_ah.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ah.c,v 1.162 2021/10/24 14:50:42 tobhe Exp $ */ +/* $OpenBSD: ip_ah.c,v 1.163 2021/10/24 17:08:27 bluhm Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -718,7 +718,7 @@ ah_input(struct mbuf **mp, struct tdb *tdb, int skip, int protoff) /* Release the crypto descriptors */ crypto_freereq(crp); - return ah_input_cb(tdb, tc, m, clen); + return ah_input_cb(tdb, tc, mp, clen); drop: m_freemp(mp); @@ -728,9 +728,10 @@ ah_input(struct mbuf **mp, struct tdb *tdb, int skip, int protoff) } int -ah_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf *m, int clen) +ah_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf **mp, int clen) { const struct auth_hash *ahx = tdb->tdb_authalgxform; + struct mbuf *m = *mp; int roff, rplen, skip, protoff; u_int64_t rpl; u_int32_t btsx, esn; @@ -890,10 +891,10 @@ ah_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf *m, int clen) free(tc, M_XDATA, 0); - return ipsec_common_input_cb(m, tdb, skip, protoff); + return ipsec_common_input_cb(mp, tdb, skip, protoff); baddone: - m_freem(m); + m_freemp(mp); free(tc, M_XDATA, 0); return -1; } diff --git a/sys/netinet/ip_esp.c b/sys/netinet/ip_esp.c index fbd793ae61f..02b0540a3d6 100644 --- a/sys/netinet/ip_esp.c +++ b/sys/netinet/ip_esp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_esp.c,v 1.182 2021/10/24 15:47:39 tobhe Exp $ */ +/* $OpenBSD: ip_esp.c,v 1.183 2021/10/24 17:08:27 bluhm Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -522,7 +522,7 @@ esp_input(struct mbuf **mp, struct tdb *tdb, int skip, int protoff) /* Release the crypto descriptors */ crypto_freereq(crp); - return esp_input_cb(tdb, abuf, skip, protoff, tdb->tdb_rpl, m, clen); + return esp_input_cb(tdb, abuf, skip, protoff, tdb->tdb_rpl, mp, clen); drop: m_freemp(mp); @@ -534,10 +534,11 @@ esp_input(struct mbuf **mp, struct tdb *tdb, int skip, int protoff) * ESP input callback, called directly by the crypto driver. */ int -esp_input_cb(struct tdb *tdb, uint8_t *abuf, int skip, int protoff, uint64_t rpl, - struct mbuf *m, int clen) +esp_input_cb(struct tdb *tdb, uint8_t *abuf, int skip, int protoff, + uint64_t rpl, struct mbuf **mp, int clen) { u_int8_t lastthree[3], aalg[AH_HMAC_MAX_HASHLEN]; + struct mbuf *m = *mp; int hlen, roff; struct mbuf *m1, *mo; const struct auth_hash *esph; @@ -710,10 +711,10 @@ esp_input_cb(struct tdb *tdb, uint8_t *abuf, int skip, int protoff, uint64_t rpl m_copyback(m, protoff, sizeof(u_int8_t), lastthree + 2, M_NOWAIT); /* Back to generic IPsec input processing */ - return ipsec_common_input_cb(m, tdb, skip, protoff); + return ipsec_common_input_cb(mp, tdb, skip, protoff); baddone: - m_freem(m); + m_freemp(mp); return -1; } diff --git a/sys/netinet/ip_ipcomp.c b/sys/netinet/ip_ipcomp.c index 404ca8c170a..a8b99ebb456 100644 --- a/sys/netinet/ip_ipcomp.c +++ b/sys/netinet/ip_ipcomp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipcomp.c,v 1.84 2021/10/24 14:50:42 tobhe Exp $ */ +/* $OpenBSD: ip_ipcomp.c,v 1.85 2021/10/24 17:08:27 bluhm Exp $ */ /* * Copyright (c) 2001 Jean-Jacques Bernard-Gundol (jj@wabbitt.org) @@ -200,7 +200,7 @@ ipcomp_input(struct mbuf **mp, struct tdb *tdb, int skip, int protoff) /* Release the crypto descriptors */ crypto_freereq(crp); - return ipcomp_input_cb(tdb, tc, m, clen); + return ipcomp_input_cb(tdb, tc, mp, clen); drop: m_freemp(mp); @@ -210,8 +210,10 @@ ipcomp_input(struct mbuf **mp, struct tdb *tdb, int skip, int protoff) } int -ipcomp_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf *m, int clen) +ipcomp_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf **mp, + int clen) { + struct mbuf *m = *mp; int skip, protoff, roff, hlen = IPCOMP_HLENGTH; u_int8_t nproto; u_int64_t ibytes; @@ -250,7 +252,8 @@ ipcomp_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf *m, int clen /* In case it's not done already, adjust the size of the mbuf chain */ m->m_pkthdr.len = clen + hlen + skip; - if ((m->m_len < skip + hlen) && (m = m_pullup(m, skip + hlen)) == 0) { + if (m->m_len < skip + hlen && + (m = *mp = m_pullup(m, skip + hlen)) == NULL) { ipcompstat_inc(ipcomps_hdrops); goto baddone; } @@ -325,10 +328,10 @@ ipcomp_input_cb(struct tdb *tdb, struct tdb_crypto *tc, struct mbuf *m, int clen m_copyback(m, protoff, sizeof(u_int8_t), &nproto, M_NOWAIT); /* Back to generic IPsec input processing */ - return ipsec_common_input_cb(m, tdb, skip, protoff); + return ipsec_common_input_cb(mp, tdb, skip, protoff); baddone: - m_freem(m); + m_freemp(mp); free(tc, M_XDATA, 0); return -1; } diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h index 9c0171de39f..a3712372fa3 100644 --- a/sys/netinet/ip_ipsp.h +++ b/sys/netinet/ip_ipsp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.h,v 1.213 2021/10/24 15:47:39 tobhe Exp $ */ +/* $OpenBSD: ip_ipsp.h,v 1.214 2021/10/24 17:08:27 bluhm Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr), @@ -571,7 +571,7 @@ int ah_attach(void); int ah_init(struct tdb *, const struct xformsw *, struct ipsecinit *); int ah_zeroize(struct tdb *); int ah_input(struct mbuf **, struct tdb *, int, int); -int ah_input_cb(struct tdb *, struct tdb_crypto *, struct mbuf *, int); +int ah_input_cb(struct tdb *, struct tdb_crypto *, struct mbuf **, int); int ah_output(struct mbuf *, struct tdb *, int, int); int ah_output_cb(struct tdb *, struct tdb_crypto *, struct mbuf *, int, int); @@ -590,7 +590,8 @@ int esp_attach(void); int esp_init(struct tdb *, const struct xformsw *, struct ipsecinit *); int esp_zeroize(struct tdb *); int esp_input(struct mbuf **, struct tdb *, int, int); -int esp_input_cb(struct tdb *, uint8_t *, int, int, uint64_t, struct mbuf *, int); +int esp_input_cb(struct tdb *, uint8_t *, int, int, uint64_t, + struct mbuf **, int); int esp_output(struct mbuf *, struct tdb *, int, int); int esp_sysctl(int *, u_int, void *, size_t *, void *, size_t); @@ -606,7 +607,7 @@ int ipcomp_attach(void); int ipcomp_init(struct tdb *, const struct xformsw *, struct ipsecinit *); int ipcomp_zeroize(struct tdb *); int ipcomp_input(struct mbuf **, struct tdb *, int, int); -int ipcomp_input_cb(struct tdb *, struct tdb_crypto *, struct mbuf *, int); +int ipcomp_input_cb(struct tdb *, struct tdb_crypto *, struct mbuf **, int); int ipcomp_output(struct mbuf *, struct tdb *, int, int); int ipcomp_output_cb(struct tdb *, struct tdb_crypto *, struct mbuf *, int, int); @@ -646,7 +647,7 @@ void ipsp_init(void); void ipsec_init(void); int ipsec_sysctl(int *, u_int, void *, size_t *, void *, size_t); int ipsec_common_input(struct mbuf **, int, int, int, int, int); -int ipsec_common_input_cb(struct mbuf *, struct tdb *, int, int); +int ipsec_common_input_cb(struct mbuf **, struct tdb *, int, int); int ipsec_delete_policy(struct ipsec_policy *); ssize_t ipsec_hdrsz(struct tdb *); void ipsec_adjust_mtu(struct mbuf *, u_int32_t); diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c index b5cea182417..1d8c3fa1201 100644 --- a/sys/netinet/ipsec_input.c +++ b/sys/netinet/ipsec_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipsec_input.c,v 1.187 2021/10/23 22:19:37 bluhm Exp $ */ +/* $OpenBSD: ipsec_input.c,v 1.188 2021/10/24 17:08:27 bluhm Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -372,8 +372,9 @@ ipsec_common_input(struct mbuf **mp, int skip, int protoff, int af, int sproto, * filtering and other sanity checks on the processed packet. */ int -ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff) +ipsec_common_input_cb(struct mbuf **mp, struct tdb *tdbp, int skip, int protoff) { + struct mbuf *m = *mp; int af, sproto; u_int8_t prot; #if NBPFILTER > 0 @@ -396,7 +397,8 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff) /* Fix IPv4 header */ if (af == AF_INET) { - if ((m->m_len < skip) && ((m = m_pullup(m, skip)) == NULL)) { + if (m->m_len < skip && + (m = *mp = m_pullup(m, skip)) == NULL) { DPRINTF("processing failed for SA %s/%08x", ipsp_address(&tdbp->tdb_dst, buf, sizeof(buf)), ntohl(tdbp->tdb_spi)); @@ -441,7 +443,7 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff) /* Fix IPv6 header */ if (af == AF_INET6) { if (m->m_len < sizeof(struct ip6_hdr) && - (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { + (m = *mp = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { DPRINTF("processing failed for SA %s/%08x", ipsp_address(&tdbp->tdb_dst, buf, sizeof(buf)), @@ -631,11 +633,11 @@ ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff) } #endif /* Call the appropriate IPsec transform callback. */ - ip_deliver(&m, &skip, prot, af); + ip_deliver(mp, &skip, prot, af); return 0; baddone: - m_freem(m); + m_freemp(mp); return -1; #undef IPSEC_ISTAT } -- 2.20.1