diff options
author | Kuniyuki Iwashima <kuniyu@amazon.com> | 2022-10-06 11:53:46 -0700 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2022-10-12 17:50:37 -0700 |
commit | 21985f43376cee092702d6cb963ff97a9d2ede68 (patch) | |
tree | 0084a093718e00e822b53495b5f506a2aee4ea15 /include/net/ipv6.h | |
parent | 3c52c6bb831f6335c176a0fc7214e26f43adbd11 (diff) | |
download | lwn-21985f43376cee092702d6cb963ff97a9d2ede68.tar.gz lwn-21985f43376cee092702d6cb963ff97a9d2ede68.zip |
udp: Call inet6_destroy_sock() in setsockopt(IPV6_ADDRFORM).
Commit 4b340ae20d0e ("IPv6: Complete IPV6_DONTFRAG support") forgot
to add a change to free inet6_sk(sk)->rxpmtu while converting an IPv6
socket into IPv4 with IPV6_ADDRFORM. After conversion, sk_prot is
changed to udp_prot and ->destroy() never cleans it up, resulting in
a memory leak.
This is due to the discrepancy between inet6_destroy_sock() and
IPV6_ADDRFORM, so let's call inet6_destroy_sock() from IPV6_ADDRFORM
to remove the difference.
However, this is not enough for now because rxpmtu can be changed
without lock_sock() after commit 03485f2adcde ("udpv6: Add lockless
sendmsg() support"). We will fix this case in the following patch.
Note we will rename inet6_destroy_sock() to inet6_cleanup_sock() and
remove unnecessary inet6_destroy_sock() calls in sk_prot->destroy()
in the future.
Fixes: 4b340ae20d0e ("IPv6: Complete IPV6_DONTFRAG support")
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include/net/ipv6.h')
-rw-r--r-- | include/net/ipv6.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index d664ba5812d8..335a49ecd8a0 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -1182,6 +1182,7 @@ void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port, void ipv6_local_error(struct sock *sk, int err, struct flowi6 *fl6, u32 info); void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu); +void inet6_cleanup_sock(struct sock *sk); int inet6_release(struct socket *sock); int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len); int inet6_getname(struct socket *sock, struct sockaddr *uaddr, |