git: 439da7f06dce - main - if_stf: KASAN fix
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 30 Nov 2021 17:36:13 UTC
The branch main has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=439da7f06dcea5af17e7d5b3b4784e54207194ac
commit 439da7f06dcea5af17e7d5b3b4784e54207194ac
Author: Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2021-11-30 15:30:22 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2021-11-30 16:35:15 +0000
if_stf: KASAN fix
In in_stf_input() we grabbed a pointer to the IPv4 header and later did
an m_pullup() before we look at the IPv6 header. However, m_pullup()
could rearrange the mbuf chain and potentially invalidate the pointer to
the IPv4 header.
Avoid this issue by copying the IP header rather than getting a pointer
to it.
Reported by: markj, Jenkins (KASAN job)
Reviewed by: markj
MFC after: 1 week
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D33192
---
sys/net/if_stf.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c
index 7807c6ebe7e9..51ea0a61ae0d 100644
--- a/sys/net/if_stf.c
+++ b/sys/net/if_stf.c
@@ -727,7 +727,7 @@ static int
in_stf_input(struct mbuf *m, int off, int proto, void *arg)
{
struct stf_softc *sc = arg;
- struct ip *ip;
+ struct ip ip;
struct ip6_hdr *ip6;
u_int8_t otos, itos;
struct ifnet *ifp;
@@ -743,7 +743,7 @@ in_stf_input(struct mbuf *m, int off, int proto, void *arg)
return (IPPROTO_DONE);
}
- ip = mtod(m, struct ip *);
+ m_copydata(m, 0, sizeof(struct ip), (caddr_t)&ip);
if (sc == NULL || (STF2IFP(sc)->if_flags & IFF_UP) == 0) {
m_freem(m);
SDT_PROBE2(if_stf, , stf_input, out, IPPROTO_DONE, __LINE__);
@@ -760,14 +760,14 @@ in_stf_input(struct mbuf *m, int off, int proto, void *arg)
* perform sanity check against outer src/dst.
* for source, perform ingress filter as well.
*/
- if (stf_checkaddr4(sc, &ip->ip_dst, NULL) < 0 ||
- stf_checkaddr4(sc, &ip->ip_src, m->m_pkthdr.rcvif) < 0) {
+ if (stf_checkaddr4(sc, &ip.ip_dst, NULL) < 0 ||
+ stf_checkaddr4(sc, &ip.ip_src, m->m_pkthdr.rcvif) < 0) {
m_freem(m);
SDT_PROBE2(if_stf, , stf_input, out, IPPROTO_DONE, __LINE__);
return (IPPROTO_DONE);
}
- otos = ip->ip_tos;
+ otos = ip.ip_tos;
m_adj(m, off);
if (m->m_len < sizeof(*ip6)) {
@@ -795,8 +795,8 @@ in_stf_input(struct mbuf *m, int off, int proto, void *arg)
* reject packets with private address range.
* (requirement from RFC3056 section 2 1st paragraph)
*/
- if ((IN6_IS_ADDR_6TO4(&ip6->ip6_src) && isrfc1918addr(&ip->ip_src)) ||
- (IN6_IS_ADDR_6TO4(&ip6->ip6_dst) && isrfc1918addr(&ip->ip_dst))) {
+ if ((IN6_IS_ADDR_6TO4(&ip6->ip6_src) && isrfc1918addr(&ip.ip_src)) ||
+ (IN6_IS_ADDR_6TO4(&ip6->ip6_dst) && isrfc1918addr(&ip.ip_dst))) {
m_freem(m);
SDT_PROBE2(if_stf, , stf_input, out, IPPROTO_DONE, __LINE__);
return (IPPROTO_DONE);