]> git.baikalelectronics.ru Git - kernel.git/commitdiff
nfp: bpf: support pointers to other stack frames for BPF-to-BPF calls
authorQuentin Monnet <quentin.monnet@netronome.com>
Sun, 7 Oct 2018 11:56:57 +0000 (12:56 +0100)
committerDaniel Borkmann <daniel@iogearbox.net>
Mon, 8 Oct 2018 08:24:13 +0000 (10:24 +0200)
Mark instructions that use pointers to areas in the stack outside of the
current stack frame, and process them accordingly in mem_op_stack().
This way, we also support BPF-to-BPF calls where the caller passes a
pointer to data in its own stack frame to the callee (typically, when
the caller passes an address to one of its local variables located in
the stack, as an argument).

Thanks to Jakub and Jiong for figuring out how to deal with this case,
I just had to turn their email discussion into this patch.

Suggested-by: Jiong Wang <jiong.wang@netronome.com>
Suggested-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Reviewed-by: Jiong Wang <jiong.wang@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
drivers/net/ethernet/netronome/nfp/bpf/jit.c
drivers/net/ethernet/netronome/nfp/bpf/main.h
drivers/net/ethernet/netronome/nfp/bpf/verifier.c

index b393f9dea5841ccbf5992fcf50272d1a877bfade..6ed1b5207ecd955f88bba1dd18dbe877b5491fac 100644 (file)
@@ -1178,7 +1178,8 @@ mem_op_stack(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
        bool lm3 = true;
        int ret;
 
-       if (meta->ptr_not_const) {
+       if (meta->ptr_not_const ||
+           meta->flags & FLAG_INSN_PTR_CALLER_STACK_FRAME) {
                /* Use of the last encountered ptr_off is OK, they all have
                 * the same alignment.  Depend on low bits of value being
                 * discarded when written to LMaddr register.
index 44b787a0bd4b4c771ebbe8805abaf3f9b5945cb1..25e10cfa2678daf47041c6dfd7f69a44b2dcbe06 100644 (file)
@@ -267,6 +267,7 @@ struct nfp_bpf_reg_state {
 
 #define FLAG_INSN_IS_JUMP_DST                  BIT(0)
 #define FLAG_INSN_IS_SUBPROG_START             BIT(1)
+#define FLAG_INSN_PTR_CALLER_STACK_FRAME       BIT(2)
 
 /**
  * struct nfp_insn_meta - BPF instruction wrapper
index f31721bd1fac8aa2e55d7afb6b7aa1827040909e..cddb70786a58451468f618bd529895b76f9a2ddc 100644 (file)
@@ -336,6 +336,9 @@ nfp_bpf_check_stack_access(struct nfp_prog *nfp_prog,
 {
        s32 old_off, new_off;
 
+       if (reg->frameno != env->cur_state->curframe)
+               meta->flags |= FLAG_INSN_PTR_CALLER_STACK_FRAME;
+
        if (!tnum_is_const(reg->var_off)) {
                pr_vlog(env, "variable ptr stack access\n");
                return -EINVAL;