From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 80A9EC433E7 for ; Sun, 18 Oct 2020 19:57:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4607722263 for ; Sun, 18 Oct 2020 19:57:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1603051057; bh=osnylhLdi+UzQudt4P3bJg4C5SW8wkL3tOjaChQhp8Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=D3jQwNbpAlzbrYZgOVLN2PrfBKrB24PtW4gUcUsuUXS8FBl1SiHKX6Rv59BCdAE7j VnlByF5CZZD8TCPkuib7swYAMi3tRE8HGjn+XvHGd8B7FoBq2WeuCi6kmgpvJgqrsV 7SsQ8yNfXQ4kY4MweYqBl6r/9+USiRCUjVcoYjHU= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388580AbgJRT5W (ORCPT ); Sun, 18 Oct 2020 15:57:22 -0400 Received: from mail.kernel.org ([198.145.29.99]:58070 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728223AbgJRTTZ (ORCPT ); Sun, 18 Oct 2020 15:19:25 -0400 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 1AF19222E8; Sun, 18 Oct 2020 19:19:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1603048764; bh=osnylhLdi+UzQudt4P3bJg4C5SW8wkL3tOjaChQhp8Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eF3wiJgXXKwi4JIYYDN001jUSR/Qe2DdRZKt4CWgEj0D/Bm8x1ndw0PmvTjBL/jYE oxsQeGNNoIT2WmIvbkEKOgFF+54RUN99Eq4dEdrwW3/bkoWjtN6Q5Smtm2wGuWNm/k 9u6x3fsH5Da+VXr5ojhcTfHFULscXdL5E15uCFWs= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Maciej Fijalkowski , Alexei Starovoitov , Sasha Levin , netdev@vger.kernel.org Subject: [PATCH AUTOSEL 5.9 064/111] bpf: Limit caller's stack depth 256 for subprogs with tailcalls Date: Sun, 18 Oct 2020 15:17:20 -0400 Message-Id: <20201018191807.4052726-64-sashal@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201018191807.4052726-1-sashal@kernel.org> References: <20201018191807.4052726-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Maciej Fijalkowski [ 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 Signed-off-by: Maciej Fijalkowski Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin --- 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 53c7bd568c5d4..5026b75db9725 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 fba52d9ec8fc4..cf9172f40ebcd 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -1489,6 +1489,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) @@ -2974,6 +2978,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