From e5fffe9a69f00d2ab88efe8e07053a4ea0588c68 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Thu, 24 Oct 2019 19:47:32 +0000 Subject: [PATCH] frag6.c: do not leak packet queue entry in error case When we are checking for the maximum reassembled packet size of the fragmentable part and run into the error case (packet too big), we are leaking the packet queue enntry if this was a first fragment to arrive. Properly cleanup, removing the queue entry from the bucket, decrementing counters, and freeing the memory. MFC after: 3 weeks Sponsored by: Netflix --- sys/netinet6/frag6.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c index 489c65926e1..ca8a8004fb3 100644 --- a/sys/netinet6/frag6.c +++ b/sys/netinet6/frag6.c @@ -572,17 +572,35 @@ frag6_input(struct mbuf **mp, int *offp, int proto) if (q6->ip6q_unfrglen >= 0) { /* The 1st fragment has already arrived. */ if (q6->ip6q_unfrglen + fragoff + frgpartlen > IPV6_MAXPACKET) { + if (only_frag) { + TAILQ_REMOVE(head, q6, ip6q_tq); + V_ip6qb[bucket].count--; + atomic_subtract_int(&V_frag6_nfragpackets, 1); +#ifdef MAC + mac_ip6q_destroy(q6); +#endif + free(q6, M_FRAG6); + } + IP6QB_UNLOCK(bucket); icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, offset - sizeof(struct ip6_frag) + offsetof(struct ip6_frag, ip6f_offlg)); - IP6QB_UNLOCK(bucket); return (IPPROTO_DONE); } } else if (fragoff + frgpartlen > IPV6_MAXPACKET) { + if (only_frag) { + TAILQ_REMOVE(head, q6, ip6q_tq); + V_ip6qb[bucket].count--; + atomic_subtract_int(&V_frag6_nfragpackets, 1); +#ifdef MAC + mac_ip6q_destroy(q6); +#endif + free(q6, M_FRAG6); + } + IP6QB_UNLOCK(bucket); icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, offset - sizeof(struct ip6_frag) + offsetof(struct ip6_frag, ip6f_offlg)); - IP6QB_UNLOCK(bucket); return (IPPROTO_DONE); }