lkml.org 
[lkml]   [2018]   [Jan]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 52/96] bpf: refactor fixup_bpf_calls()
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Alexei Starovoitov <ast@fb.com>

    commit 79741b3bdec01a8628368fbcfccc7d189ed606cb upstream.

    reduce indent and make it iterate over instructions similar to
    convert_ctx_accesses(). Also convert hard BUG_ON into soft verifier error.

    Signed-off-by: Alexei Starovoitov <ast@kernel.org>
    Acked-by: Daniel Borkmann <daniel@iogearbox.net>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Cc: Jiri Slaby <jslaby@suse.cz>
    [Backported to 4.9.y - gregkh]
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    kernel/bpf/verifier.c | 75 +++++++++++++++++++++++---------------------------
    1 file changed, 35 insertions(+), 40 deletions(-)

    --- a/kernel/bpf/verifier.c
    +++ b/kernel/bpf/verifier.c
    @@ -3362,55 +3362,50 @@ static int convert_ctx_accesses(struct b
    return 0;
    }

    -/* fixup insn->imm field of bpf_call instructions:
    - * if (insn->imm == BPF_FUNC_map_lookup_elem)
    - * insn->imm = bpf_map_lookup_elem - __bpf_call_base;
    - * else if (insn->imm == BPF_FUNC_map_update_elem)
    - * insn->imm = bpf_map_update_elem - __bpf_call_base;
    - * else ...
    +/* fixup insn->imm field of bpf_call instructions
    *
    * this function is called after eBPF program passed verification
    */
    -static void fixup_bpf_calls(struct bpf_prog *prog)
    +static int fixup_bpf_calls(struct bpf_verifier_env *env)
    {
    + struct bpf_prog *prog = env->prog;
    + struct bpf_insn *insn = prog->insnsi;
    const struct bpf_func_proto *fn;
    + const int insn_cnt = prog->len;
    int i;

    - for (i = 0; i < prog->len; i++) {
    - struct bpf_insn *insn = &prog->insnsi[i];
    -
    - if (insn->code == (BPF_JMP | BPF_CALL)) {
    - /* we reach here when program has bpf_call instructions
    - * and it passed bpf_check(), means that
    - * ops->get_func_proto must have been supplied, check it
    - */
    - BUG_ON(!prog->aux->ops->get_func_proto);
    -
    - if (insn->imm == BPF_FUNC_get_route_realm)
    - prog->dst_needed = 1;
    - if (insn->imm == BPF_FUNC_get_prandom_u32)
    - bpf_user_rnd_init_once();
    - if (insn->imm == BPF_FUNC_tail_call) {
    - /* mark bpf_tail_call as different opcode
    - * to avoid conditional branch in
    - * interpeter for every normal call
    - * and to prevent accidental JITing by
    - * JIT compiler that doesn't support
    - * bpf_tail_call yet
    - */
    - insn->imm = 0;
    - insn->code |= BPF_X;
    - continue;
    - }
    + for (i = 0; i < insn_cnt; i++, insn++) {
    + if (insn->code != (BPF_JMP | BPF_CALL))
    + continue;
    +
    + if (insn->imm == BPF_FUNC_get_route_realm)
    + prog->dst_needed = 1;
    + if (insn->imm == BPF_FUNC_get_prandom_u32)
    + bpf_user_rnd_init_once();
    + if (insn->imm == BPF_FUNC_tail_call) {
    + /* mark bpf_tail_call as different opcode to avoid
    + * conditional branch in the interpeter for every normal
    + * call and to prevent accidental JITing by JIT compiler
    + * that doesn't support bpf_tail_call yet
    + */
    + insn->imm = 0;
    + insn->code |= BPF_X;
    + continue;
    + }

    - fn = prog->aux->ops->get_func_proto(insn->imm);
    - /* all functions that have prototype and verifier allowed
    - * programs to call them, must be real in-kernel functions
    - */
    - BUG_ON(!fn->func);
    - insn->imm = fn->func - __bpf_call_base;
    + fn = prog->aux->ops->get_func_proto(insn->imm);
    + /* all functions that have prototype and verifier allowed
    + * programs to call them, must be real in-kernel functions
    + */
    + if (!fn->func) {
    + verbose("kernel subsystem misconfigured func %d\n",
    + insn->imm);
    + return -EFAULT;
    }
    + insn->imm = fn->func - __bpf_call_base;
    }
    +
    + return 0;
    }

    static void free_states(struct bpf_verifier_env *env)
    @@ -3515,7 +3510,7 @@ skip_full_check:
    ret = convert_ctx_accesses(env);

    if (ret == 0)
    - fixup_bpf_calls(env->prog);
    + ret = fixup_bpf_calls(env);

    if (log_level && log_len >= log_size - 1) {
    BUG_ON(log_len >= log_size);

    \
     
     \ /
      Last update: 2018-01-15 14:45    [W:2.151 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site