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>
