public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Jakub Kicinski <kuba@kernel.org>,
	Wen Gu <guwen@linux.alibaba.com>,
	Hawkins Jiawei <yin31149@gmail.com>,
	Jakub Sitnicki <jakub@cloudflare.com>,
	syzbot+5f26f85569bd179c18ce@syzkaller.appspotmail.com
Subject: [PATCH 5.15 31/73] net: fix refcount bug in sk_psock_get (2)
Date: Fri,  2 Sep 2022 14:18:55 +0200	[thread overview]
Message-ID: <20220902121405.463164532@linuxfoundation.org> (raw)
In-Reply-To: <20220902121404.435662285@linuxfoundation.org>

From: Hawkins Jiawei <yin31149@gmail.com>

commit 2a0133723f9ebeb751cfce19f74ec07e108bef1f upstream.

Syzkaller reports refcount bug as follows:
------------[ cut here ]------------
refcount_t: saturated; leaking memory.
WARNING: CPU: 1 PID: 3605 at lib/refcount.c:19 refcount_warn_saturate+0xf4/0x1e0 lib/refcount.c:19
Modules linked in:
CPU: 1 PID: 3605 Comm: syz-executor208 Not tainted 5.18.0-syzkaller-03023-g7e062cda7d90 #0
 <TASK>
 __refcount_add_not_zero include/linux/refcount.h:163 [inline]
 __refcount_inc_not_zero include/linux/refcount.h:227 [inline]
 refcount_inc_not_zero include/linux/refcount.h:245 [inline]
 sk_psock_get+0x3bc/0x410 include/linux/skmsg.h:439
 tls_data_ready+0x6d/0x1b0 net/tls/tls_sw.c:2091
 tcp_data_ready+0x106/0x520 net/ipv4/tcp_input.c:4983
 tcp_data_queue+0x25f2/0x4c90 net/ipv4/tcp_input.c:5057
 tcp_rcv_state_process+0x1774/0x4e80 net/ipv4/tcp_input.c:6659
 tcp_v4_do_rcv+0x339/0x980 net/ipv4/tcp_ipv4.c:1682
 sk_backlog_rcv include/net/sock.h:1061 [inline]
 __release_sock+0x134/0x3b0 net/core/sock.c:2849
 release_sock+0x54/0x1b0 net/core/sock.c:3404
 inet_shutdown+0x1e0/0x430 net/ipv4/af_inet.c:909
 __sys_shutdown_sock net/socket.c:2331 [inline]
 __sys_shutdown_sock net/socket.c:2325 [inline]
 __sys_shutdown+0xf1/0x1b0 net/socket.c:2343
 __do_sys_shutdown net/socket.c:2351 [inline]
 __se_sys_shutdown net/socket.c:2349 [inline]
 __x64_sys_shutdown+0x50/0x70 net/socket.c:2349
 do_syscall_x64 arch/x86/entry/common.c:50 [inline]
 do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
 entry_SYSCALL_64_after_hwframe+0x46/0xb0
 </TASK>

During SMC fallback process in connect syscall, kernel will
replaces TCP with SMC. In order to forward wakeup
smc socket waitqueue after fallback, kernel will sets
clcsk->sk_user_data to origin smc socket in
smc_fback_replace_callbacks().

Later, in shutdown syscall, kernel will calls
sk_psock_get(), which treats the clcsk->sk_user_data
as psock type, triggering the refcnt warning.

So, the root cause is that smc and psock, both will use
sk_user_data field. So they will mismatch this field
easily.

This patch solves it by using another bit(defined as
SK_USER_DATA_PSOCK) in PTRMASK, to mark whether
sk_user_data points to a psock object or not.
This patch depends on a PTRMASK introduced in commit f1ff5ce2cd5e
("net, sk_msg: Clear sk_user_data pointer on clone if tagged").

For there will possibly be more flags in the sk_user_data field,
this patch also refactor sk_user_data flags code to be more generic
to improve its maintainability.

Reported-and-tested-by: syzbot+5f26f85569bd179c18ce@syzkaller.appspotmail.com
Suggested-by: Jakub Kicinski <kuba@kernel.org>
Acked-by: Wen Gu <guwen@linux.alibaba.com>
Signed-off-by: Hawkins Jiawei <yin31149@gmail.com>
Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/linux/skmsg.h |    3 +-
 include/net/sock.h    |   68 +++++++++++++++++++++++++++++++++++---------------
 net/core/skmsg.c      |    4 ++
 3 files changed, 53 insertions(+), 22 deletions(-)

--- a/include/linux/skmsg.h
+++ b/include/linux/skmsg.h
@@ -283,7 +283,8 @@ static inline void sk_msg_sg_copy_clear(
 
 static inline struct sk_psock *sk_psock(const struct sock *sk)
 {
-	return rcu_dereference_sk_user_data(sk);
+	return __rcu_dereference_sk_user_data_with_flags(sk,
+							 SK_USER_DATA_PSOCK);
 }
 
 static inline void sk_psock_set_state(struct sk_psock *psock,
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -543,14 +543,26 @@ enum sk_pacing {
 	SK_PACING_FQ		= 2,
 };
 
-/* Pointer stored in sk_user_data might not be suitable for copying
- * when cloning the socket. For instance, it can point to a reference
- * counted object. sk_user_data bottom bit is set if pointer must not
- * be copied.
+/* flag bits in sk_user_data
+ *
+ * - SK_USER_DATA_NOCOPY:      Pointer stored in sk_user_data might
+ *   not be suitable for copying when cloning the socket. For instance,
+ *   it can point to a reference counted object. sk_user_data bottom
+ *   bit is set if pointer must not be copied.
+ *
+ * - SK_USER_DATA_BPF:         Mark whether sk_user_data field is
+ *   managed/owned by a BPF reuseport array. This bit should be set
+ *   when sk_user_data's sk is added to the bpf's reuseport_array.
+ *
+ * - SK_USER_DATA_PSOCK:       Mark whether pointer stored in
+ *   sk_user_data points to psock type. This bit should be set
+ *   when sk_user_data is assigned to a psock object.
  */
 #define SK_USER_DATA_NOCOPY	1UL
-#define SK_USER_DATA_BPF	2UL	/* Managed by BPF */
-#define SK_USER_DATA_PTRMASK	~(SK_USER_DATA_NOCOPY | SK_USER_DATA_BPF)
+#define SK_USER_DATA_BPF	2UL
+#define SK_USER_DATA_PSOCK	4UL
+#define SK_USER_DATA_PTRMASK	~(SK_USER_DATA_NOCOPY | SK_USER_DATA_BPF |\
+				  SK_USER_DATA_PSOCK)
 
 /**
  * sk_user_data_is_nocopy - Test if sk_user_data pointer must not be copied
@@ -563,24 +575,40 @@ static inline bool sk_user_data_is_nocop
 
 #define __sk_user_data(sk) ((*((void __rcu **)&(sk)->sk_user_data)))
 
+/**
+ * __rcu_dereference_sk_user_data_with_flags - return the pointer
+ * only if argument flags all has been set in sk_user_data. Otherwise
+ * return NULL
+ *
+ * @sk: socket
+ * @flags: flag bits
+ */
+static inline void *
+__rcu_dereference_sk_user_data_with_flags(const struct sock *sk,
+					  uintptr_t flags)
+{
+	uintptr_t sk_user_data = (uintptr_t)rcu_dereference(__sk_user_data(sk));
+
+	WARN_ON_ONCE(flags & SK_USER_DATA_PTRMASK);
+
+	if ((sk_user_data & flags) == flags)
+		return (void *)(sk_user_data & SK_USER_DATA_PTRMASK);
+	return NULL;
+}
+
 #define rcu_dereference_sk_user_data(sk)				\
+	__rcu_dereference_sk_user_data_with_flags(sk, 0)
+#define __rcu_assign_sk_user_data_with_flags(sk, ptr, flags)		\
 ({									\
-	void *__tmp = rcu_dereference(__sk_user_data((sk)));		\
-	(void *)((uintptr_t)__tmp & SK_USER_DATA_PTRMASK);		\
-})
-#define rcu_assign_sk_user_data(sk, ptr)				\
-({									\
-	uintptr_t __tmp = (uintptr_t)(ptr);				\
-	WARN_ON_ONCE(__tmp & ~SK_USER_DATA_PTRMASK);			\
-	rcu_assign_pointer(__sk_user_data((sk)), __tmp);		\
-})
-#define rcu_assign_sk_user_data_nocopy(sk, ptr)				\
-({									\
-	uintptr_t __tmp = (uintptr_t)(ptr);				\
-	WARN_ON_ONCE(__tmp & ~SK_USER_DATA_PTRMASK);			\
+	uintptr_t __tmp1 = (uintptr_t)(ptr),				\
+		  __tmp2 = (uintptr_t)(flags);				\
+	WARN_ON_ONCE(__tmp1 & ~SK_USER_DATA_PTRMASK);			\
+	WARN_ON_ONCE(__tmp2 & SK_USER_DATA_PTRMASK);			\
 	rcu_assign_pointer(__sk_user_data((sk)),			\
-			   __tmp | SK_USER_DATA_NOCOPY);		\
+			   __tmp1 | __tmp2);				\
 })
+#define rcu_assign_sk_user_data(sk, ptr)				\
+	__rcu_assign_sk_user_data_with_flags(sk, ptr, 0)
 
 /*
  * SK_CAN_REUSE and SK_NO_REUSE on a socket mean that the socket is OK
--- a/net/core/skmsg.c
+++ b/net/core/skmsg.c
@@ -731,7 +731,9 @@ struct sk_psock *sk_psock_init(struct so
 	sk_psock_set_state(psock, SK_PSOCK_TX_ENABLED);
 	refcount_set(&psock->refcnt, 1);
 
-	rcu_assign_sk_user_data_nocopy(sk, psock);
+	__rcu_assign_sk_user_data_with_flags(sk, psock,
+					     SK_USER_DATA_NOCOPY |
+					     SK_USER_DATA_PSOCK);
 	sock_hold(sk);
 
 out:



  parent reply	other threads:[~2022-09-02 12:50 UTC|newest]

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-02 12:18 [PATCH 5.15 00/73] 5.15.65-rc1 review Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 01/73] mm: Force TLB flush for PFNMAP mappings before unlink_file_vma() Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 02/73] drm/bridge: Add stubs for devm_drm_of_get_bridge when OF is disabled Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 03/73] ACPI: thermal: drop an always true check Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 04/73] drm/vc4: hdmi: Rework power up Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 05/73] drm/vc4: hdmi: Depends on CONFIG_PM Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 06/73] firmware: tegra: bpmp: Do only aligned access to IPC memory area Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 07/73] crypto: lib - remove unneeded selection of XOR_BLOCKS Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 08/73] Drivers: hv: balloon: Support status report for larger page sizes Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 09/73] mm/hugetlb: avoid corrupting page->mapping in hugetlb_mcopy_atomic_pte Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 10/73] arm64: errata: Add Cortex-A510 to the repeat tlbi list Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 11/73] io_uring: correct fill events helpers types Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 12/73] io_uring: clean cqe filling functions Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 13/73] io_uring: refactor poll update Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 14/73] io_uring: move common poll bits Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 15/73] io_uring: kill poll linking optimisation Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 16/73] io_uring: inline io_poll_complete Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 17/73] io_uring: poll rework Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 18/73] io_uring: Remove unused function req_ref_put Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 19/73] io_uring: remove poll entry from list when canceling all Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 20/73] io_uring: bump poll refs to full 31-bits Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 21/73] io_uring: fail links when poll fails Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 22/73] io_uring: fix wrong arm_poll error handling Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 23/73] io_uring: fix UAF due to missing POLLFREE handling Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 24/73] kbuild: Fix include path in scripts/Makefile.modpost Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 25/73] Bluetooth: L2CAP: Fix build errors in some archs Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 26/73] Revert "PCI/portdrv: Dont disable AER reporting in get_port_device_capability()" Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 27/73] HID: steam: Prevent NULL pointer dereference in steam_{recv,send}_report Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 28/73] udmabuf: Set the DMA mask for the udmabuf device (v2) Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 29/73] media: pvrusb2: fix memory leak in pvr_probe Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 30/73] HID: hidraw: fix memory leak in hidraw_release() Greg Kroah-Hartman
2022-09-02 12:18 ` Greg Kroah-Hartman [this message]
2022-09-02 12:18 ` [PATCH 5.15 32/73] fbdev: fb_pm2fb: Avoid potential divide by zero error Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 33/73] ftrace: Fix NULL pointer dereference in is_ftrace_trampoline when ftrace is dead Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 34/73] bpf: Dont redirect packets with invalid pkt_len Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 35/73] mm/rmap: Fix anon_vma->degree ambiguity leading to double-reuse Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 36/73] ALSA: usb-audio: Add quirk for LH Labs Geek Out HD Audio 1V5 Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 37/73] HID: add Lenovo Yoga C630 battery quirk Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 38/73] HID: AMD_SFH: Add a DMI quirk entry for Chromebooks Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 39/73] HID: asus: ROG NKey: Ignore portion of 0x5a report Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 40/73] HID: thrustmaster: Add sparco wheel and fix array length Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 41/73] drm/i915/gt: Skip TLB invalidations once wedged Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 42/73] mmc: mtk-sd: Clear interrupts when cqe off/disable Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 43/73] mmc: sdhci-of-dwcmshc: add reset call back for rockchip Socs Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 44/73] mmc: sdhci-of-dwcmshc: rename rk3568 to rk35xx Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 45/73] mmc: sdhci-of-dwcmshc: Re-enable support for the BlueField-3 SoC Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 46/73] btrfs: remove root argument from btrfs_unlink_inode() Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 47/73] btrfs: remove no longer needed logic for replaying directory deletes Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 48/73] btrfs: add and use helper for unlinking inode during log replay Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 49/73] btrfs: fix warning during log replay when bumping inode link count Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 50/73] fs/ntfs3: Fix work with fragmented xattr Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 51/73] ASoC: sh: rz-ssi: Improve error handling in rz_ssi_probe() error path Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 52/73] drm/amd/display: Avoid MPC infinite loop Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 53/73] drm/amd/display: Fix HDMI VSIF V3 incorrect issue Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 54/73] drm/amd/display: For stereo keep "FLIP_ANY_FRAME" Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 55/73] drm/amd/display: clear optc underflow before turn off odm clock Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 56/73] ksmbd: return STATUS_BAD_NETWORK_NAME error status if share is not configured Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 57/73] neigh: fix possible DoS due to net iface start/stop loop Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 58/73] s390/hypfs: avoid error message under KVM Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 59/73] ksmbd: dont remove dos attribute xattr on O_TRUNC open Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 60/73] drm/amd/pm: add missing ->fini_microcode interface for Sienna Cichlid Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 61/73] drm/amd/display: Fix pixel clock programming Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 62/73] drm/amdgpu: Increase tlb flush timeout for sriov Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 63/73] drm/amd/display: avoid doing vm_init multiple time Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 64/73] netfilter: conntrack: NF_CONNTRACK_PROCFS should no longer default to y Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 65/73] testing: selftests: nft_flowtable.sh: use random netns names Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 66/73] btrfs: move lockdep class helpers to locking.c Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 67/73] btrfs: fix lockdep splat with reloc root extent buffers Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 68/73] btrfs: tree-checker: check for overlapping extent items Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 69/73] kprobes: dont call disarm_kprobe() for disabled kprobes Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 70/73] btrfs: fix space cache corruption and potential double allocations Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 71/73] android: binder: fix lockdep check on clearing vma Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 72/73] net/af_packet: check len when min_header_len equals to 0 Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 73/73] net: neigh: dont call kfree_skb() under spin_lock_irqsave() Greg Kroah-Hartman
2022-09-02 16:36 ` [PATCH 5.15 00/73] 5.15.65-rc1 review Jon Hunter
2022-09-02 18:00 ` Florian Fainelli
2022-09-02 22:06 ` Shuah Khan
2022-09-03  0:36 ` Guenter Roeck
2022-09-03  3:33 ` Naresh Kamboju
2022-09-03  4:10 ` Bagas Sanjaya
2022-09-03  7:42 ` Ron Economos
2022-09-03 10:47 ` Sudip Mukherjee

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220902121405.463164532@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=guwen@linux.alibaba.com \
    --cc=jakub@cloudflare.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=syzbot+5f26f85569bd179c18ce@syzkaller.appspotmail.com \
    --cc=yin31149@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox