From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Maciej Fijalkowski <maciej.fijalkowski@intel.com>,
Alexei Starovoitov <ast@kernel.org>,
Sasha Levin <sashal@kernel.org>,
netdev@vger.kernel.org
Subject: [PATCH AUTOSEL 5.8 061/101] bpf: Limit caller's stack depth 256 for subprogs with tailcalls
Date: Sun, 18 Oct 2020 15:19:46 -0400 [thread overview]
Message-ID: <20201018192026.4053674-61-sashal@kernel.org> (raw)
In-Reply-To: <20201018192026.4053674-1-sashal@kernel.org>
From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
[ Upstream commit 7f6e4312e15a5c370e84eaa685879b6bdcc717e4 ]
Protect against potential stack overflow that might happen when bpf2bpf
calls get combined with tailcalls. Limit the caller's stack depth for
such case down to 256 so that the worst case scenario would result in 8k
stack size (32 which is tailcall limit * 256 = 8k).
Suggested-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/bpf_verifier.h | 1 +
kernel/bpf/verifier.c | 29 +++++++++++++++++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index ca08db4ffb5f7..ce3f5231aa698 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -358,6 +358,7 @@ struct bpf_subprog_info {
u32 start; /* insn idx of function entry point */
u32 linfo_idx; /* The idx to the main_prog->aux->linfo */
u16 stack_depth; /* max. stack depth used by this function */
+ bool has_tail_call;
};
/* single container for all structs
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 89b07db146763..17145f8f81979 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1470,6 +1470,10 @@ static int check_subprogs(struct bpf_verifier_env *env)
for (i = 0; i < insn_cnt; i++) {
u8 code = insn[i].code;
+ if (code == (BPF_JMP | BPF_CALL) &&
+ insn[i].imm == BPF_FUNC_tail_call &&
+ insn[i].src_reg != BPF_PSEUDO_CALL)
+ subprog[cur_subprog].has_tail_call = true;
if (BPF_CLASS(code) != BPF_JMP && BPF_CLASS(code) != BPF_JMP32)
goto next;
if (BPF_OP(code) == BPF_EXIT || BPF_OP(code) == BPF_CALL)
@@ -2951,6 +2955,31 @@ static int check_max_stack_depth(struct bpf_verifier_env *env)
int ret_prog[MAX_CALL_FRAMES];
process_func:
+ /* protect against potential stack overflow that might happen when
+ * bpf2bpf calls get combined with tailcalls. Limit the caller's stack
+ * depth for such case down to 256 so that the worst case scenario
+ * would result in 8k stack size (32 which is tailcall limit * 256 =
+ * 8k).
+ *
+ * To get the idea what might happen, see an example:
+ * func1 -> sub rsp, 128
+ * subfunc1 -> sub rsp, 256
+ * tailcall1 -> add rsp, 256
+ * func2 -> sub rsp, 192 (total stack size = 128 + 192 = 320)
+ * subfunc2 -> sub rsp, 64
+ * subfunc22 -> sub rsp, 128
+ * tailcall2 -> add rsp, 128
+ * func3 -> sub rsp, 32 (total stack size 128 + 192 + 64 + 32 = 416)
+ *
+ * tailcall will unwind the current stack frame but it will not get rid
+ * of caller's stack as shown on the example above.
+ */
+ if (idx && subprog[idx].has_tail_call && depth >= 256) {
+ verbose(env,
+ "tail_calls are not allowed when call stack of previous frames is %d bytes. Too large\n",
+ depth);
+ return -EACCES;
+ }
/* round up to 32-bytes, since this is granularity
* of interpreter stack size
*/
--
2.25.1
next prev parent reply other threads:[~2020-10-18 19:49 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20201018192026.4053674-1-sashal@kernel.org>
2020-10-18 19:19 ` [PATCH AUTOSEL 5.8 033/101] ipv6/icmp: l3mdev: Perform icmp error route lookup on source device routing table (v2) Sasha Levin
2020-10-18 19:19 ` [PATCH AUTOSEL 5.8 035/101] ip_gre: set dev->hard_header_len and dev->needed_headroom properly Sasha Levin
2020-10-18 19:19 ` [PATCH AUTOSEL 5.8 036/101] mac80211: handle lack of sband->bitrates in rates Sasha Levin
2020-10-18 19:19 ` [PATCH AUTOSEL 5.8 039/101] bpf: Use raw_spin_trylock() for pcpu_freelist_push/pop in NMI Sasha Levin
2020-10-18 19:19 ` [PATCH AUTOSEL 5.8 047/101] rtw88: pci: Power cycle device during shutdown Sasha Levin
2020-10-18 19:19 ` [PATCH AUTOSEL 5.8 050/101] rtw88: increse the size of rx buffer size Sasha Levin
2020-10-18 19:19 ` [PATCH AUTOSEL 5.8 051/101] selftests/bpf: Fix overflow tests to reflect iter size increase Sasha Levin
2020-10-18 19:19 ` [PATCH AUTOSEL 5.8 055/101] can: flexcan: flexcan_chip_stop(): add error handling and propagate error value Sasha Levin
2020-10-18 19:19 ` [PATCH AUTOSEL 5.8 057/101] ath9k: hif_usb: fix race condition between usb_get_urb() and usb_kill_anchored_urbs() Sasha Levin
2020-10-18 19:19 ` Sasha Levin [this message]
2020-10-18 19:19 ` [PATCH AUTOSEL 5.8 068/101] Bluetooth: Only mark socket zapped after unlocking Sasha Levin
2020-10-18 19:19 ` [PATCH AUTOSEL 5.8 073/101] selftests/bpf: Fix test_sysctl_loop{1, 2} failure due to clang change Sasha Levin
2020-10-18 19:19 ` [PATCH AUTOSEL 5.8 074/101] brcmsmac: fix memory leak in wlc_phy_attach_lcnphy Sasha Levin
2020-10-18 19:20 ` [PATCH AUTOSEL 5.8 075/101] rtl8xxxu: prevent potential memory leak Sasha Levin
2020-10-18 19:20 ` [PATCH AUTOSEL 5.8 086/101] ipvs: Fix uninit-value in do_ip_vs_set_ctl() Sasha Levin
2020-10-18 19:20 ` [PATCH AUTOSEL 5.8 089/101] mwifiex: don't call del_timer_sync() on uninitialized timer Sasha Levin
2020-10-18 19:20 ` [PATCH AUTOSEL 5.8 095/101] brcm80211: fix possible memleak in brcmf_proto_msgbuf_attach Sasha Levin
2020-10-18 19:20 ` [PATCH AUTOSEL 5.8 101/101] ath10k: check idx validity in __ath10k_htt_rx_ring_fill_n() 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=20201018192026.4053674-61-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=ast@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maciej.fijalkowski@intel.com \
--cc=netdev@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;
as well as URLs for NNTP newsgroup(s).