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
MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D29838
This commit is contained in:
Mark Johnston 2021-04-21 15:38:01 -04:00
parent 6648383803
commit 652908599b
4 changed files with 28 additions and 0 deletions

View File

@ -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;
}

View File

@ -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 *);
/*

View File

@ -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;
}

View File

@ -1113,6 +1113,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.