]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
bpf/verifier: introduce BPF_PTR_TO_MAP_VALUE
authorRoman Gushchin <guro@fb.com>
Thu, 2 Aug 2018 21:27:22 +0000 (14:27 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Thu, 2 Aug 2018 22:47:32 +0000 (00:47 +0200)
BPF_MAP_TYPE_CGROUP_STORAGE maps are special in a way
that the access from the bpf program side is lookup-free.
That means the result is guaranteed to be a valid
pointer to the cgroup storage; no NULL-check is required.

This patch introduces BPF_PTR_TO_MAP_VALUE return type,
which is required to cause the verifier accept programs,
which are not checking the map value pointer for being NULL.

Signed-off-by: Roman Gushchin <guro@fb.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
include/linux/bpf.h
kernel/bpf/verifier.c

index 16be67888c3084a650a8bd927fbbd6e16e177329..ca4ac2a39defd6f5b8ffaf773b28dc48e510c6e1 100644 (file)
@@ -155,6 +155,7 @@ enum bpf_arg_type {
 enum bpf_return_type {
        RET_INTEGER,                    /* function returns integer */
        RET_VOID,                       /* function doesn't return anything */
+       RET_PTR_TO_MAP_VALUE,           /* returns a pointer to map elem value */
        RET_PTR_TO_MAP_VALUE_OR_NULL,   /* returns a pointer to map elem value or NULL */
 };
 
index 7e75434a9e54040d3a37b76ba7f986fea288538a..1ede16c8bb4081e06fde4181466b7d7ecb130ddf 100644 (file)
@@ -2545,8 +2545,12 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
                mark_reg_unknown(env, regs, BPF_REG_0);
        } else if (fn->ret_type == RET_VOID) {
                regs[BPF_REG_0].type = NOT_INIT;
-       } else if (fn->ret_type == RET_PTR_TO_MAP_VALUE_OR_NULL) {
-               regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL;
+       } else if (fn->ret_type == RET_PTR_TO_MAP_VALUE_OR_NULL ||
+                  fn->ret_type == RET_PTR_TO_MAP_VALUE) {
+               if (fn->ret_type == RET_PTR_TO_MAP_VALUE)
+                       regs[BPF_REG_0].type = PTR_TO_MAP_VALUE;
+               else
+                       regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL;
                /* There is no offset yet applied, variable or fixed */
                mark_reg_known_zero(env, regs, BPF_REG_0);
                regs[BPF_REG_0].off = 0;