]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
bpf: Limit caller's stack depth 256 for subprogs with tailcalls
authorMaciej Fijalkowski <maciej.fijalkowski@intel.com>
Wed, 16 Sep 2020 21:10:07 +0000 (23:10 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Oct 2020 09:12:15 +0000 (10:12 +0100)
[ 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
kernel/bpf/verifier.c

index 53c7bd568c5d4099fc4e67df935b117c4d82aeaf..5026b75db9725d7f518ca9e7288f7d4fe37c0c03 100644 (file)
@@ -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
index c38ebc9af94687d7ee4c37aab4d1805485553535..43cd175c66a55755476d7ee4921ba1b3b65b6d02 100644 (file)
@@ -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
         */