git: 730e18a4607c - stable/15 - rawip: Fix handling of checksums in rip6_input()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 17 Aug 2026 12:10:19 UTC
The branch stable/15 has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=730e18a4607cdec7ace37808455acda0585f31fa
commit 730e18a4607cdec7ace37808455acda0585f31fa
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-08-04 13:35:35 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-08-17 12:07:41 +0000
rawip: Fix handling of checksums in rip6_input()
A v6 raw socket may ask the kernel to validate the checksum of an
inbound packet. If it does, and the validation fails, we discard the
packet, but this isn't really right: other raw sockets may wish to
receive a copy of the packet anyway.
Rework checksum handling to address this problem, and use a flag to
avoid computing the checksum more than once for a given packet.
Fixes: de2d47842e880281 ("SMR protection for inpcbs")
Reviewed by: pouria, glebius
Reported by: Yunzhi Ke
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D58559
(cherry picked from commit 196874ce2e97e3e6425493b1d501e716b356bc36)
---
sys/netinet6/raw_ip6.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index ea12626893a4..8e080f43cbdd 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -191,7 +191,8 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
struct rip6_inp_match_ctx ctx = { .ip6 = ip6, .proto = proto };
struct inpcb_iterator inpi = INP_ITERATOR(&V_ripcbinfo,
INPLOOKUP_RLOCKPCB, rip6_inp_match, &ctx);
- int delivered = 0, fib;
+ int cksum, delivered = 0, fib;
+ bool cksum_computed = false;
M_ASSERTPKTHDR(m);
NET_EPOCH_ASSERT();
@@ -231,19 +232,22 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
*/
continue;
if (inp->in6p_cksum != -1) {
- RIP6STAT_INC(rip6s_isum);
- if (m->m_pkthdr.len - (*offp + inp->in6p_cksum) < 2 ||
- in6_cksum(m, proto, *offp,
- m->m_pkthdr.len - *offp)) {
- RIP6STAT_INC(rip6s_badsum);
+ if (m->m_pkthdr.len - (*offp + inp->in6p_cksum) < 2)
+ continue;
+ if (!cksum_computed) {
+ cksum = in6_cksum(m, proto, *offp,
+ m->m_pkthdr.len - *offp);
+ cksum_computed = true;
+ RIP6STAT_INC(rip6s_isum);
+ if (cksum != 0)
+ RIP6STAT_INC(rip6s_badsum);
+ }
+ if (cksum != 0) {
/*
- * Drop the received message, don't send an
- * ICMP6 message. Set proto to IPPROTO_NONE
- * to achieve that.
+ * Drop the packet, don't send an ICMP6 message.
*/
- INP_RUNLOCK(inp);
proto = IPPROTO_NONE;
- break;
+ continue;
}
}
/*