From 00dd3bb2049dbfa2ca2fd0b35881ee3ec0c5180e Mon Sep 17 00:00:00 2001 From: bluhm Date: Tue, 26 Mar 2024 23:48:49 +0000 Subject: [PATCH] Additional length check for IPv6 reassembled fragments. FreeBSD-SA-23:06.ipv6 security advisory has added an additional overflow check in frag6_input(). OpenBSD is not affected by that as the bug was introduced by another change in 2019. The existing code is complicated and NetBSD has taken the FreeBSD fix, although they were also not affected. The additional check makes the complicated code more robust. Length calculation taken from NetBSD. Discussed with FreeBSD. OK sashan@ mvs@ --- sys/netinet6/frag6.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c index 5ecb11f1cb0..1b528b30b99 100644 --- a/sys/netinet6/frag6.c +++ b/sys/netinet6/frag6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: frag6.c,v 1.87 2022/02/22 01:15:02 guenther Exp $ */ +/* $OpenBSD: frag6.c,v 1.88 2024/03/26 23:48:49 bluhm Exp $ */ /* $KAME: frag6.c,v 1.40 2002/05/27 21:40:31 itojun Exp $ */ /* @@ -404,8 +404,17 @@ frag6_input(struct mbuf **mp, int *offp, int proto, int af) /* adjust offset to point where the original next header starts */ offset = ip6af->ip6af_offset - sizeof(struct ip6_frag); pool_put(&ip6af_pool, ip6af); + next += offset - sizeof(struct ip6_hdr); + if ((u_int)next > IPV6_MAXPACKET) { + TAILQ_REMOVE(&frag6_queue, q6, ip6q_queue); + frag6_nfrags -= q6->ip6q_nfrag; + frag6_nfragpackets--; + mtx_leave(&frag6_mutex); + pool_put(&ip6q_pool, q6); + goto dropfrag; + } ip6 = mtod(m, struct ip6_hdr *); - ip6->ip6_plen = htons((u_short)next + offset - sizeof(struct ip6_hdr)); + ip6->ip6_plen = htons(next); ip6->ip6_src = q6->ip6q_src; ip6->ip6_dst = q6->ip6q_dst; if (q6->ip6q_ecn == IPTOS_ECN_CE) -- 2.20.1