From: Greg Kroah-Hartman Date: Mon, 7 Nov 2022 09:09:15 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v4.9.333~58 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=46c4113d66c4ad43c5a07f9fecc280a2efc034e0;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: tcp-udp-fix-memory-leak-in-ipv6_renew_options.patch --- diff --git a/queue-5.4/series b/queue-5.4/series index adc0e4139ed..2b1a102bf74 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -42,3 +42,4 @@ xfs-don-t-fail-unwritten-extent-conversion-on-writeback-due-to-edquot.patch xfs-add-the-missed-xfs_perag_put-for-xfs_ifree_cluster.patch bluetooth-l2cap-fix-attempting-to-access-uninitialized-memory.patch block-bfq-protect-bfqd-queued-by-bfqd-lock.patch +tcp-udp-fix-memory-leak-in-ipv6_renew_options.patch diff --git a/queue-5.4/tcp-udp-fix-memory-leak-in-ipv6_renew_options.patch b/queue-5.4/tcp-udp-fix-memory-leak-in-ipv6_renew_options.patch new file mode 100644 index 00000000000..3fa28897a11 --- /dev/null +++ b/queue-5.4/tcp-udp-fix-memory-leak-in-ipv6_renew_options.patch @@ -0,0 +1,100 @@ +From 3c52c6bb831f6335c176a0fc7214e26f43adbd11 Mon Sep 17 00:00:00 2001 +From: Kuniyuki Iwashima +Date: Thu, 6 Oct 2022 11:53:45 -0700 +Subject: tcp/udp: Fix memory leak in ipv6_renew_options(). + +From: Kuniyuki Iwashima + +commit 3c52c6bb831f6335c176a0fc7214e26f43adbd11 upstream. + +syzbot reported a memory leak [0] related to IPV6_ADDRFORM. + +The scenario is that while one thread is converting an IPv6 socket into +IPv4 with IPV6_ADDRFORM, another thread calls do_ipv6_setsockopt() and +allocates memory to inet6_sk(sk)->XXX after conversion. + +Then, the converted sk with (tcp|udp)_prot never frees the IPv6 resources, +which inet6_destroy_sock() should have cleaned up. + +setsockopt(IPV6_ADDRFORM) setsockopt(IPV6_DSTOPTS) ++-----------------------+ +----------------------+ +- do_ipv6_setsockopt(sk, ...) + - sockopt_lock_sock(sk) - do_ipv6_setsockopt(sk, ...) + - lock_sock(sk) ^._ called via tcpv6_prot + - WRITE_ONCE(sk->sk_prot, &tcp_prot) before WRITE_ONCE() + - xchg(&np->opt, NULL) + - txopt_put(opt) + - sockopt_release_sock(sk) + - release_sock(sk) - sockopt_lock_sock(sk) + - lock_sock(sk) + - ipv6_set_opt_hdr(sk, ...) + - ipv6_update_options(sk, opt) + - xchg(&inet6_sk(sk)->opt, opt) + ^._ opt is never freed. + + - sockopt_release_sock(sk) + - release_sock(sk) + +Since IPV6_DSTOPTS allocates options under lock_sock(), we can avoid this +memory leak by testing whether sk_family is changed by IPV6_ADDRFORM after +acquiring the lock. + +This issue exists from the initial commit between IPV6_ADDRFORM and +IPV6_PKTOPTIONS. + +[0]: +BUG: memory leak +unreferenced object 0xffff888009ab9f80 (size 96): + comm "syz-executor583", pid 328, jiffies 4294916198 (age 13.034s) + hex dump (first 32 bytes): + 01 00 00 00 48 00 00 00 08 00 00 00 00 00 00 00 ....H........... + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + [<000000002ee98ae1>] kmalloc include/linux/slab.h:605 [inline] + [<000000002ee98ae1>] sock_kmalloc+0xb3/0x100 net/core/sock.c:2566 + [<0000000065d7b698>] ipv6_renew_options+0x21e/0x10b0 net/ipv6/exthdrs.c:1318 + [<00000000a8c756d7>] ipv6_set_opt_hdr net/ipv6/ipv6_sockglue.c:354 [inline] + [<00000000a8c756d7>] do_ipv6_setsockopt.constprop.0+0x28b7/0x4350 net/ipv6/ipv6_sockglue.c:668 + [<000000002854d204>] ipv6_setsockopt+0xdf/0x190 net/ipv6/ipv6_sockglue.c:1021 + [<00000000e69fdcf8>] tcp_setsockopt+0x13b/0x2620 net/ipv4/tcp.c:3789 + [<0000000090da4b9b>] __sys_setsockopt+0x239/0x620 net/socket.c:2252 + [<00000000b10d192f>] __do_sys_setsockopt net/socket.c:2263 [inline] + [<00000000b10d192f>] __se_sys_setsockopt net/socket.c:2260 [inline] + [<00000000b10d192f>] __x64_sys_setsockopt+0xbe/0x160 net/socket.c:2260 + [<000000000a80d7aa>] do_syscall_x64 arch/x86/entry/common.c:50 [inline] + [<000000000a80d7aa>] do_syscall_64+0x38/0x90 arch/x86/entry/common.c:80 + [<000000004562b5c6>] entry_SYSCALL_64_after_hwframe+0x63/0xcd + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzbot +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Jakub Kicinski +Signed-off-by: Meena Shanmugam +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ipv6_sockglue.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/net/ipv6/ipv6_sockglue.c ++++ b/net/ipv6/ipv6_sockglue.c +@@ -164,6 +164,12 @@ static int do_ipv6_setsockopt(struct soc + rtnl_lock(); + lock_sock(sk); + ++ /* Another thread has converted the socket into IPv4 with ++ * IPV6_ADDRFORM concurrently. ++ */ ++ if (unlikely(sk->sk_family != AF_INET6)) ++ goto unlock; ++ + switch (optname) { + + case IPV6_ADDRFORM: +@@ -924,6 +930,7 @@ pref_skip_coa: + break; + } + ++unlock: + release_sock(sk); + if (needs_rtnl) + rtnl_unlock();