linux-stable/net
Kuniyuki Iwashima 0c5d628f1e tcp/udp: Fix memory leak in ipv6_renew_options().
commit 3c52c6bb83 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: 1da177e4c3 ("Linux-2.6.12-rc2")
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Meena Shanmugam <meenashanmugam@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-11-04 00:00:35 +09:00
..
6lowpan
9p
802
8021q
appletalk
atm net/atm: fix proc_mpc_write incorrect return value 2022-10-29 10:08:32 +02:00
ax25
batman-adv
bluetooth Bluetooth: L2CAP: Fix user-after-free 2022-10-21 12:39:11 +02:00
bpf
bpfilter
bridge netfilter: ebtables: fix memory leak when blob is malformed 2022-09-20 23:50:03 +02:00
caif
can can: j1939: transport: j1939_session_skb_drop_old(): spin_unlock_irqrestore() before kfree_skb() 2022-11-04 00:00:17 +09:00
ceph
core net: do not sense pfmemalloc status in skb_append_pagefrags() 2022-11-04 00:00:34 +09:00
dcb
dccp
decnet
dns_resolver
dsa
ethernet
ethtool ethtool: eeprom: fix null-deref on genl_info in dump 2022-11-04 00:00:24 +09:00
hsr net: hsr: avoid possible NULL deref in skb_clone() 2022-10-29 10:08:34 +02:00
ieee802154 net: ieee802154: fix error return code in dgram_bind() 2022-11-04 00:00:25 +09:00
ife
ipv4 nh: fix scope used to find saddr when adding non gw nh 2022-11-04 00:00:33 +09:00
ipv6 tcp/udp: Fix memory leak in ipv6_renew_options(). 2022-11-04 00:00:35 +09:00
iucv
kcm kcm: do not sense pfmemalloc status in kcm_sendpage() 2022-11-04 00:00:34 +09:00
key
l2tp
l3mdev
lapb
llc
mac80211 wifi: mac80211: accept STA changes without link changes 2022-10-21 12:39:06 +02:00
mac802154 mac802154: Fix LQI recording 2022-11-04 00:00:21 +09:00
mctp mctp: prevent double key removal and unref 2022-10-15 08:02:58 +02:00
mpls
mptcp mptcp: set msk local address earlier 2022-11-04 00:00:31 +09:00
ncsi
netfilter netfilter: nf_tables: relax NFTA_SET_ELEM_KEY_END set flags requirements 2022-10-29 10:08:34 +02:00
netlabel
netlink
netrom
nfc
nsh
openvswitch openvswitch: switch from WARN to pr_warn 2022-11-04 00:00:33 +09:00
packet
phonet
psample
qrtr
rds net: rds: don't hold sock lock when cancelling work from rds_tcp_reset_callbacks() 2022-10-21 12:38:20 +02:00
rfkill
rose
rxrpc
sched net: sched: fix race condition in qdisc_graft() 2022-10-29 10:08:35 +02:00
sctp sctp: handle the error returned from sctp_auth_asoc_init_active_key 2022-10-21 12:38:19 +02:00
smc net/smc: Fix an error code in smc_lgr_create() 2022-10-29 10:08:32 +02:00
strparser
sunrpc NFS client bugfixes for Linux 6.0 2022-09-12 17:53:46 -04:00
switchdev
tipc tipc: fix a null-ptr-deref in tipc_topsrv_accept 2022-11-04 00:00:29 +09:00
tls tls: strp: make sure the TCP skbs do not have overlapping data 2022-10-29 10:08:32 +02:00
unix af_unix: Fix memory leaks of the whole sk due to OOB skb. 2022-10-21 12:38:20 +02:00
vmw_vsock vhost/vsock: Use kvmalloc/kvfree for larger packets. 2022-10-21 12:38:19 +02:00
wireless wifi: cfg80211: get correct AP link chandef 2022-10-21 12:38:03 +02:00
x25
xdp xsk: Fix backpressure mechanism on Tx 2022-10-21 12:38:05 +02:00
xfrm xfrm: Update ipcomp_scratches with NULL when freed 2022-10-21 12:39:07 +02:00
compat.c net: clear msg_get_inq in __get_compat_msghdr() 2022-09-20 08:23:20 -07:00
devres.c
Kconfig
Kconfig.debug
Makefile
socket.c
sysctl_net.c