diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2024-03-26 23:48:50 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2024-03-26 23:48:50 +0000 |
commit | efb18f0a4498dd75d7db0ccb02bc00bf3ebeb0a8 (patch) | |
tree | fac01e584a530a7776e57c92c48d5f5208645ba6 /sys/netinet6/frag6.c | |
parent | 46cb954358266bcfc31bc5f89434d89903df4e6c (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/frag6.c')
-rw-r--r-- | sys/netinet6/frag6.c | 13 |
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) |