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
This commit is contained in:
parent
7792f70137
commit
e5fffe9a69
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user