public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: stable@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: John Fastabend <john.fastabend@gmail.com>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Sasha Levin <alexander.levin@microsoft.com>
Subject: [PATCH AUTOSEL 4.18 45/58] bpf: sockmap, fix transition through disconnect without close
Date: Mon,  8 Oct 2018 11:25:10 -0400	[thread overview]
Message-ID: <20181008152523.70705-45-sashal@kernel.org> (raw)
In-Reply-To: <20181008152523.70705-1-sashal@kernel.org>

From: John Fastabend <john.fastabend@gmail.com>

[ Upstream commit b05545e15e1ff1d6a6a8593971275f9cc3e6b92b ]

It is possible (via shutdown()) for TCP socks to go trough TCP_CLOSE
state via tcp_disconnect() without actually calling tcp_close which
would then call our bpf_tcp_close() callback. Because of this a user
could disconnect a socket then put it in a LISTEN state which would
break our assumptions about sockets always being ESTABLISHED state.

To resolve this rely on the unhash hook, which is called in the
disconnect case, to remove the sock from the sockmap.

Reported-by: Eric Dumazet <edumazet@google.com>
Fixes: 1aa12bdf1bfb ("bpf: sockmap, add sock close() hook to remove socks")
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
Acked-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
---
 kernel/bpf/sockmap.c | 60 ++++++++++++++++++++++++++++++--------------
 1 file changed, 41 insertions(+), 19 deletions(-)

diff --git a/kernel/bpf/sockmap.c b/kernel/bpf/sockmap.c
index 0d829e71024b..6cdef7f3bd69 100644
--- a/kernel/bpf/sockmap.c
+++ b/kernel/bpf/sockmap.c
@@ -132,6 +132,7 @@ struct smap_psock {
 	struct work_struct gc_work;
 
 	struct proto *sk_proto;
+	void (*save_unhash)(struct sock *sk);
 	void (*save_close)(struct sock *sk, long timeout);
 	void (*save_data_ready)(struct sock *sk);
 	void (*save_write_space)(struct sock *sk);
@@ -143,6 +144,7 @@ static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 static int bpf_tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size);
 static int bpf_tcp_sendpage(struct sock *sk, struct page *page,
 			    int offset, size_t size, int flags);
+static void bpf_tcp_unhash(struct sock *sk);
 static void bpf_tcp_close(struct sock *sk, long timeout);
 
 static inline struct smap_psock *smap_psock_sk(const struct sock *sk)
@@ -184,6 +186,7 @@ static void build_protos(struct proto prot[SOCKMAP_NUM_CONFIGS],
 			 struct proto *base)
 {
 	prot[SOCKMAP_BASE]			= *base;
+	prot[SOCKMAP_BASE].unhash		= bpf_tcp_unhash;
 	prot[SOCKMAP_BASE].close		= bpf_tcp_close;
 	prot[SOCKMAP_BASE].recvmsg		= bpf_tcp_recvmsg;
 	prot[SOCKMAP_BASE].stream_memory_read	= bpf_tcp_stream_read;
@@ -217,6 +220,7 @@ static int bpf_tcp_init(struct sock *sk)
 		return -EBUSY;
 	}
 
+	psock->save_unhash = sk->sk_prot->unhash;
 	psock->save_close = sk->sk_prot->close;
 	psock->sk_proto = sk->sk_prot;
 
@@ -305,30 +309,12 @@ static struct smap_psock_map_entry *psock_map_pop(struct sock *sk,
 	return e;
 }
 
-static void bpf_tcp_close(struct sock *sk, long timeout)
+static void bpf_tcp_remove(struct sock *sk, struct smap_psock *psock)
 {
-	void (*close_fun)(struct sock *sk, long timeout);
 	struct smap_psock_map_entry *e;
 	struct sk_msg_buff *md, *mtmp;
-	struct smap_psock *psock;
 	struct sock *osk;
 
-	lock_sock(sk);
-	rcu_read_lock();
-	psock = smap_psock_sk(sk);
-	if (unlikely(!psock)) {
-		rcu_read_unlock();
-		release_sock(sk);
-		return sk->sk_prot->close(sk, timeout);
-	}
-
-	/* The psock may be destroyed anytime after exiting the RCU critial
-	 * section so by the time we use close_fun the psock may no longer
-	 * be valid. However, bpf_tcp_close is called with the sock lock
-	 * held so the close hook and sk are still valid.
-	 */
-	close_fun = psock->save_close;
-
 	if (psock->cork) {
 		free_start_sg(psock->sock, psock->cork);
 		kfree(psock->cork);
@@ -379,6 +365,42 @@ static void bpf_tcp_close(struct sock *sk, long timeout)
 		kfree(e);
 		e = psock_map_pop(sk, psock);
 	}
+}
+
+static void bpf_tcp_unhash(struct sock *sk)
+{
+	void (*unhash_fun)(struct sock *sk);
+	struct smap_psock *psock;
+
+	rcu_read_lock();
+	psock = smap_psock_sk(sk);
+	if (unlikely(!psock)) {
+		rcu_read_unlock();
+		if (sk->sk_prot->unhash)
+			sk->sk_prot->unhash(sk);
+		return;
+	}
+	unhash_fun = psock->save_unhash;
+	bpf_tcp_remove(sk, psock);
+	rcu_read_unlock();
+	unhash_fun(sk);
+}
+
+static void bpf_tcp_close(struct sock *sk, long timeout)
+{
+	void (*close_fun)(struct sock *sk, long timeout);
+	struct smap_psock *psock;
+
+	lock_sock(sk);
+	rcu_read_lock();
+	psock = smap_psock_sk(sk);
+	if (unlikely(!psock)) {
+		rcu_read_unlock();
+		release_sock(sk);
+		return sk->sk_prot->close(sk, timeout);
+	}
+	close_fun = psock->save_close;
+	bpf_tcp_remove(sk, psock);
 	rcu_read_unlock();
 	release_sock(sk);
 	close_fun(sk, timeout);
-- 
2.17.1


  parent reply	other threads:[~2018-10-08 15:34 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-08 15:24 [PATCH AUTOSEL 4.18 01/58] soundwire: Fix duplicate stream state assignment Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 02/58] soundwire: Fix incorrect exit after configuring stream Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 03/58] soundwire: Fix acquiring bus lock twice during master release Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 04/58] media: af9035: prevent buffer overflow on write Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 05/58] spi: gpio: Fix copy-and-paste error Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 06/58] batman-adv: Avoid probe ELP information leak Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 07/58] batman-adv: Fix segfault when writing to throughput_override Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 08/58] batman-adv: Fix segfault when writing to sysfs elp_interval Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 09/58] batman-adv: Prevent duplicated gateway_node entry Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 10/58] batman-adv: Prevent duplicated nc_node entry Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 11/58] batman-adv: Prevent duplicated softif_vlan entry Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 12/58] batman-adv: Prevent duplicated global TT entry Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 13/58] batman-adv: Prevent duplicated tvlv handler Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 14/58] batman-adv: fix backbone_gw refcount on queue_work() failure Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 15/58] batman-adv: fix hardif_neigh " Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 16/58] cxgb4: fix abort_req_rss6 struct Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 17/58] clocksource/drivers/ti-32k: Add CLOCK_SOURCE_SUSPEND_NONSTOP flag for non-am43 SoCs Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 18/58] ucma: fix a use-after-free in ucma_resolve_ip() Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 19/58] scsi: ibmvscsis: Fix a stringop-overflow warning Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 20/58] scsi: ibmvscsis: Ensure partition name is properly NUL terminated Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 21/58] net/mlx5: Check for SQ and not RQ state when modifying hairpin SQ Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 22/58] intel_th: pci: Add Ice Lake PCH support Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 23/58] Input: atakbd - fix Atari keymap Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 24/58] Input: atakbd - fix Atari CapsLock behaviour Sasha Levin
2018-10-08 17:11   ` Dmitry Torokhov
2018-10-08 19:09     ` Michael Schmitz
2018-10-08 19:20       ` Dmitry Torokhov
2018-10-09 22:05         ` Michael Schmitz
2018-10-10  6:59           ` Geert Uytterhoeven
2018-10-10 23:38             ` Michael Schmitz
2018-10-10 14:29         ` Sasha Levin
2018-10-10 17:02           ` Dmitry Torokhov
2018-10-10 18:11             ` Sasha Levin
2018-10-10 18:28               ` Greg KH
2018-10-10 18:40                 ` Dmitry Torokhov
2018-10-10 18:49                   ` Sasha Levin
2018-10-10 18:58                     ` Dmitry Torokhov
2018-10-10 19:02                       ` Sasha Levin
2018-10-10 18:36               ` Dmitry Torokhov
2018-10-10 19:00                 ` Sasha Levin
2018-10-10 19:04             ` Geert Uytterhoeven
2018-10-12  0:03               ` Dmitry Torokhov
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 25/58] net: stmmac: Rework coalesce timer and fix multi-queue races Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 26/58] net: stmmac: Fixup the tail addr setting in xmit path Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 27/58] selftests: pmtu: properly redirect stderr to /dev/null Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 28/58] net: emac: fix fixed-link setup for the RTL8363SB switch Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 29/58] ravb: do not write 1 to reserved bits Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 30/58] net/smc: fix non-blocking connect problem Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 31/58] net/smc: fix sizeof to int comparison Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 32/58] net: mvpp2: fix a txq_done race condition Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 33/58] sfp: fix oops with ethtool -m Sasha Levin
2018-10-08 15:24 ` [PATCH AUTOSEL 4.18 34/58] qed: Fix populating the invalid stag value in multi function mode Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 35/58] qed: Do not add VLAN 0 tag to untagged frames in multi-function mode Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 36/58] bnxt_en: don't try to offload VLAN 'modify' action Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 37/58] PCI: dwc: Fix scheduling while atomic issues Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 38/58] RDMA/uverbs: Fix validity check for modify QP Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 39/58] scsi: lpfc: Synchronize access to remoteport via rport Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 40/58] drm: mali-dp: Call drm_crtc_vblank_reset on device init Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 41/58] net: mscc: fix the frame extraction into the skb Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 42/58] scsi: ipr: System hung while dlpar adding primary ipr adapter back Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 43/58] scsi: sd: don't crash the host on invalid commands Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 44/58] bpf: sockmap only allow ESTABLISHED sock state Sasha Levin
2018-10-08 15:25 ` Sasha Levin [this message]
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 46/58] bpf: test_maps, only support ESTABLISHED socks Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 47/58] net/mlx4: Use cpumask_available for eq->affinity_mask Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 48/58] clocksource/drivers/fttmr010: Fix set_next_event handler Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 49/58] net: aquantia: memory corruption on jumbo frames Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 50/58] RDMA/bnxt_re: Fix system crash during RDMA resource initialization Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 51/58] RISC-V: include linux/ftrace.h in asm-prototypes.h Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 52/58] iommu/rockchip: Free irqs in shutdown handler Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 53/58] pinctrl/amd: poll InterruptEnable bits in amd_gpio_irq_set_type Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 54/58] powerpc/tm: Fix userspace r13 corruption Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 55/58] powerpc/tm: Avoid possible userspace r1 corruption on reclaim Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 56/58] powerpc/numa: Use associativity if VPHN hcall is successful Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 57/58] iommu/amd: Return devid as alias for ACPI HID devices Sasha Levin
2018-10-08 15:25 ` [PATCH AUTOSEL 4.18 58/58] x86/boot: Fix kexec booting failure in the SEV bit detection code Sasha Levin

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=20181008152523.70705-45-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=alexander.levin@microsoft.com \
    --cc=daniel@iogearbox.net \
    --cc=john.fastabend@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /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