Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 05 Aug 2026 13:13:50 +0000
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 196874ce2e97 - main - rawip: Fix handling of checksums in rip6_input()
Message-ID:  <6a73370e.375f2.32de99f3@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=196874ce2e97e3e6425493b1d501e716b356bc36

commit 196874ce2e97e3e6425493b1d501e716b356bc36
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-08-04 13:35:35 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-08-05 13:09:08 +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
---
 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 8c503f70af0f..dcf3db251629 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -190,7 +190,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();
@@ -230,19 +231,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;
 			}
 		}
 		/*


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a73370e.375f2.32de99f3>