git: 196874ce2e97 - main - rawip: Fix handling of checksums in rip6_input()

Mark Johnston <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a73370e.375f2.32de99f3__11874.842974224$1785935660$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by markj:

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

commit 196874ce2e97e3e6425493b1d501e716b356bc36
Author:     Mark Johnston <[email protected]>
AuthorDate: 2026-08-04 13:35:35 +0000
Commit:     Mark Johnston <[email protected]>
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;
 			}
 		}
 		/*
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.