diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2023-07-20 12:08:24 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2023-07-21 18:51:13 +0000 |
commit | bc310a95c58a3c570ed7e5103371453881e36ba1 (patch) | |
tree | 426dc5bba90a9713fb84b338ba63560883b9227e | |
parent | ff4633d9f897c2247bc67930740509a1ba315c81 (diff) | |
download | src-bc310a95c58a3c570ed7e5103371453881e36ba1.tar.gz src-bc310a95c58a3c570ed7e5103371453881e36ba1.zip |
ip output: ensure that mbufs are mapped if ipsec is enabled
Ipsec needs access to packet headers to determine if a policy is
applicable. It seems that typically IP headers are mapped, but the code
is arguably needs to check this before blindly accessing them. Then,
operations like m_unshare() and m_makespace() are not yet ready for
unmapped mbufs.
Ensure that the packet is mapped before calling into IPSEC_OUTPUT().
PR: 272616
Reviewed by: jhb, markj
Sponsored by: NVidia networking
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D41112
-rw-r--r-- | sys/netinet/ip_output.c | 6 | ||||
-rw-r--r-- | sys/netinet6/ip6_output.c | 6 |
2 files changed, 12 insertions, 0 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 1976ab9803af..3f30c63cdc87 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -671,6 +671,12 @@ again: sendit: #if defined(IPSEC) || defined(IPSEC_SUPPORT) if (IPSEC_ENABLED(ipv4)) { + m = mb_unmapped_to_ext(m); + if (m == NULL) { + IPSTAT_INC(ips_odropped); + error = ENOBUFS; + goto bad; + } if ((error = IPSEC_OUTPUT(ipv4, m, inp)) != 0) { if (error == EINPROGRESS) error = 0; diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 59ac04842854..7e3c98270cc2 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -461,6 +461,12 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt, * XXX: need scope argument. */ if (IPSEC_ENABLED(ipv6)) { + m = mb_unmapped_to_ext(m); + if (m == NULL) { + IP6STAT_INC(ip6s_odropped); + error = ENOBUFS; + goto bad; + } if ((error = IPSEC_OUTPUT(ipv6, m, inp)) != 0) { if (error == EINPROGRESS) error = 0; |