summaryrefslogtreecommitdiff
path: root/sys/netinet6
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2024-03-26 23:48:50 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2024-03-26 23:48:50 +0000
commitefb18f0a4498dd75d7db0ccb02bc00bf3ebeb0a8 (patch)
treefac01e584a530a7776e57c92c48d5f5208645ba6 /sys/netinet6
parent46cb954358266bcfc31bc5f89434d89903df4e6c (diff)
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@
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/frag6.c13
1 files 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)