aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2021-04-21 19:38:01 +0000
committerMark Johnston <markj@FreeBSD.org>2021-04-28 14:00:13 +0000
commit2b826286c3b951df0bb3b4250eecbb7adc5c860b (patch)
treea87183446a46109a9f100e1dc32b15276b4e8edb
parent29246f2cb0c5c5c06c73e99dc0d6c947f62c7dc4 (diff)
downloadsrc-2b826286c3b951df0bb3b4250eecbb7adc5c860b.tar.gz
src-2b826286c3b951df0bb3b4250eecbb7adc5c860b.zip
Add required checks for unmapped mbufs in ipdivert and ipfw
Also add an M_ASSERTMAPPED() macro to verify that all mbufs in the chain are mapped. Use it in ipfw_nat, which operates on a chain returned by m_megapullup(). PR: 255164 Reviewed by: ae, gallatin Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D29838 (cherry picked from commit 652908599b6fa7285ee60cb567b97e70b648ac29)
-rw-r--r--sys/netinet/ip_divert.c6
-rw-r--r--sys/netpfil/ipfw/ip_fw_nat.c1
-rw-r--r--sys/netpfil/ipfw/nat64/nat64_translate.c10
-rw-r--r--sys/sys/mbuf.h11
4 files changed, 28 insertions, 0 deletions
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index 70d3fbd1f230..c3f9c43b8f70 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -212,11 +212,17 @@ divert_packet(struct mbuf *m, bool incoming)
/* Delayed checksums are currently not compatible with divert. */
if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
+ m = mb_unmapped_to_ext(m);
+ if (m == NULL)
+ return;
in_delayed_cksum(m);
m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
}
#if defined(SCTP) || defined(SCTP_SUPPORT)
if (m->m_pkthdr.csum_flags & CSUM_SCTP) {
+ m = mb_unmapped_to_ext(m);
+ if (m == NULL)
+ return;
sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2));
m->m_pkthdr.csum_flags &= ~CSUM_SCTP;
}
diff --git a/sys/netpfil/ipfw/ip_fw_nat.c b/sys/netpfil/ipfw/ip_fw_nat.c
index bcda3cff011c..d7b31c29d4ec 100644
--- a/sys/netpfil/ipfw/ip_fw_nat.c
+++ b/sys/netpfil/ipfw/ip_fw_nat.c
@@ -307,6 +307,7 @@ ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, struct mbuf *m)
args->m = NULL;
return (IP_FW_DENY);
}
+ M_ASSERTMAPPED(mcl);
ip = mtod(mcl, struct ip *);
/*
diff --git a/sys/netpfil/ipfw/nat64/nat64_translate.c b/sys/netpfil/ipfw/nat64/nat64_translate.c
index 4ed3bfa765f6..29666a7d3a9a 100644
--- a/sys/netpfil/ipfw/nat64/nat64_translate.c
+++ b/sys/netpfil/ipfw/nat64/nat64_translate.c
@@ -1296,6 +1296,11 @@ nat64_do_handle_ip4(struct mbuf *m, struct in6_addr *saddr,
/* Handle delayed checksums if needed. */
if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
+ m = mb_unmapped_to_ext(m);
+ if (m == NULL) {
+ NAT64STAT_INC(&cfg->stats, nomem);
+ return (NAT64RETURN);
+ }
in_delayed_cksum(m);
m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
}
@@ -1673,6 +1678,11 @@ nat64_do_handle_ip6(struct mbuf *m, uint32_t aaddr, uint16_t aport,
/* Handle delayed checksums if needed. */
if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) {
+ m = mb_unmapped_to_ext(m);
+ if (m == NULL) {
+ NAT64STAT_INC(&cfg->stats, nomem);
+ return (NAT64RETURN);
+ }
in6_delayed_cksum(m, plen, hlen);
m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6;
}
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index 0a249b6e2c6a..9c18ebd4943d 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -1110,6 +1110,17 @@ m_extrefcnt(struct mbuf *m)
KASSERT((((struct mbuf *)m)->m_flags & 0) == 0, \
("%s: attempted use of a free mbuf!", __func__))
+/* Check whether any mbuf in the chain is unmapped. */
+#ifdef INVARIANTS
+#define M_ASSERTMAPPED(m) do { \
+ for (struct mbuf *__m = (m); __m != NULL; __m = __m->m_next) \
+ KASSERT((__m->m_flags & M_EXTPG) == 0, \
+ ("%s: chain %p contains an unmapped mbuf", __func__, (m)));\
+} while (0)
+#else
+#define M_ASSERTMAPPED(m)
+#endif
+
/*
* Return the address of the start of the buffer associated with an mbuf,
* handling external storage, packet-header mbufs, and regular data mbufs.