Since we are offloading this program to the host, some of the helper calls will not make sense. For example get_numa_node_id. Some helpers can not be used because we don't handle them yet. So let's allow a small set of helper calls for now. Signed-off-by: Prashant Bhole <prashantbhole.linux@xxxxxxxxx> --- drivers/net/virtio_net.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 91a94b787c64..ab5be6b95bbd 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -2549,6 +2549,25 @@ static struct virtnet_bpf_map *virtnet_get_bpf_map(struct virtnet_info *vi, return NULL; } +static int virtnet_bpf_check_helper_call(struct bpf_insn *insn) +{ + switch (insn->imm) { + case BPF_FUNC_map_lookup_elem: + case BPF_FUNC_map_update_elem: + case BPF_FUNC_map_delete_elem: + case BPF_FUNC_ktime_get_ns: + case BPF_FUNC_get_prandom_u32: + case BPF_FUNC_csum_update: + case BPF_FUNC_xdp_adjust_head: + case BPF_FUNC_xdp_adjust_meta: + case BPF_FUNC_xdp_adjust_tail: + case BPF_FUNC_strtol: + case BPF_FUNC_strtoul: + return 0; + } + return -EOPNOTSUPP; +} + static int virtnet_bpf_verify_insn(struct bpf_verifier_env *env, int insn_idx, int prev_insn) { @@ -2830,6 +2849,7 @@ static int virtnet_bpf_verifier_setup(struct bpf_prog *prog) struct virtnet_bpf_bound_prog *state; struct virtnet_bpf_map *virtnet_map; struct bpf_map *map; + u8 opcode, class; struct fd mapfd; int i, err = 0; @@ -2846,6 +2866,16 @@ static int virtnet_bpf_verifier_setup(struct bpf_prog *prog) for (i = 0; i < state->len; i++) { struct bpf_insn *insn = &state->insnsi[i]; + opcode = BPF_OP(insn->code); + class = BPF_CLASS(insn->code); + + if ((class == BPF_JMP || class == BPF_JMP32) && + opcode == BPF_CALL && insn->src_reg != BPF_PSEUDO_CALL) { + if (virtnet_bpf_check_helper_call(insn)) + return -EOPNOTSUPP; + continue; + } + if (insn->code != (BPF_LD | BPF_IMM | BPF_DW)) continue; -- 2.20.1