OSDN Git Service

selftests/bpf: Generalize dummy program types
[android-x86/kernel.git] / tools / testing / selftests / bpf / test_verifier.c
index 67c412d..809d8e9 100644 (file)
@@ -70,7 +70,7 @@ struct bpf_test {
        int fixup_cgroup_storage[MAX_FIXUPS];
        const char *errstr;
        const char *errstr_unpriv;
-       uint32_t retval;
+       uint32_t retval, retval_unpriv;
        enum {
                UNDEF,
                ACCEPT,
@@ -2002,29 +2002,27 @@ static struct bpf_test tests[] = {
                .result = ACCEPT,
        },
        {
-               "check skb->hash byte load not permitted 1",
+               "check skb->hash byte load permitted 1",
                .insns = {
                        BPF_MOV64_IMM(BPF_REG_0, 0),
                        BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
                                    offsetof(struct __sk_buff, hash) + 1),
                        BPF_EXIT_INSN(),
                },
-               .errstr = "invalid bpf_context access",
-               .result = REJECT,
+               .result = ACCEPT,
        },
        {
-               "check skb->hash byte load not permitted 2",
+               "check skb->hash byte load permitted 2",
                .insns = {
                        BPF_MOV64_IMM(BPF_REG_0, 0),
                        BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
                                    offsetof(struct __sk_buff, hash) + 2),
                        BPF_EXIT_INSN(),
                },
-               .errstr = "invalid bpf_context access",
-               .result = REJECT,
+               .result = ACCEPT,
        },
        {
-               "check skb->hash byte load not permitted 3",
+               "check skb->hash byte load permitted 3",
                .insns = {
                        BPF_MOV64_IMM(BPF_REG_0, 0),
 #if __BYTE_ORDER == __LITTLE_ENDIAN
@@ -2036,8 +2034,7 @@ static struct bpf_test tests[] = {
 #endif
                        BPF_EXIT_INSN(),
                },
-               .errstr = "invalid bpf_context access",
-               .result = REJECT,
+               .result = ACCEPT,
        },
        {
                "check cb access: byte, wrong type",
@@ -2149,7 +2146,7 @@ static struct bpf_test tests[] = {
                .result = ACCEPT,
        },
        {
-               "check skb->hash half load not permitted",
+               "check skb->hash half load permitted 2",
                .insns = {
                        BPF_MOV64_IMM(BPF_REG_0, 0),
 #if __BYTE_ORDER == __LITTLE_ENDIAN
@@ -2161,6 +2158,37 @@ static struct bpf_test tests[] = {
 #endif
                        BPF_EXIT_INSN(),
                },
+               .result = ACCEPT,
+       },
+       {
+               "check skb->hash half load not permitted, unaligned 1",
+               .insns = {
+                       BPF_MOV64_IMM(BPF_REG_0, 0),
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+                       BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
+                                   offsetof(struct __sk_buff, hash) + 1),
+#else
+                       BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
+                                   offsetof(struct __sk_buff, hash) + 3),
+#endif
+                       BPF_EXIT_INSN(),
+               },
+               .errstr = "invalid bpf_context access",
+               .result = REJECT,
+       },
+       {
+               "check skb->hash half load not permitted, unaligned 3",
+               .insns = {
+                       BPF_MOV64_IMM(BPF_REG_0, 0),
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+                       BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
+                                   offsetof(struct __sk_buff, hash) + 3),
+#else
+                       BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_1,
+                                   offsetof(struct __sk_buff, hash) + 1),
+#endif
+                       BPF_EXIT_INSN(),
+               },
                .errstr = "invalid bpf_context access",
                .result = REJECT,
        },
@@ -2448,6 +2476,7 @@ static struct bpf_test tests[] = {
                },
                .result = REJECT,
                .errstr = "invalid stack off=-79992 size=8",
+               .errstr_unpriv = "R1 stack pointer arithmetic goes out of range",
        },
        {
                "PTR_TO_STACK store/load - out of bounds high",
@@ -2749,6 +2778,19 @@ static struct bpf_test tests[] = {
                .result = ACCEPT,
        },
        {
+               "alu32: mov u32 const",
+               .insns = {
+                       BPF_MOV32_IMM(BPF_REG_7, 0),
+                       BPF_ALU32_IMM(BPF_AND, BPF_REG_7, 1),
+                       BPF_MOV32_REG(BPF_REG_0, BPF_REG_7),
+                       BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
+                       BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_7, 0),
+                       BPF_EXIT_INSN(),
+               },
+               .result = ACCEPT,
+               .retval = 0,
+       },
+       {
                "unpriv: partial copy of pointer",
                .insns = {
                        BPF_MOV32_REG(BPF_REG_1, BPF_REG_10),
@@ -2823,7 +2865,7 @@ static struct bpf_test tests[] = {
                .result = ACCEPT,
        },
        {
-               "unpriv: adding of fp",
+               "unpriv: adding of fp, reg",
                .insns = {
                        BPF_MOV64_IMM(BPF_REG_0, 0),
                        BPF_MOV64_IMM(BPF_REG_1, 0),
@@ -2831,6 +2873,21 @@ static struct bpf_test tests[] = {
                        BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, -8),
                        BPF_EXIT_INSN(),
                },
+               .errstr_unpriv = "R1 stack pointer arithmetic goes out of range",
+               .result_unpriv = REJECT,
+               .result = ACCEPT,
+       },
+       {
+               "unpriv: adding of fp, imm",
+               .insns = {
+               BPF_MOV64_IMM(BPF_REG_0, 0),
+               BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
+               BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0),
+               BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, -8),
+               BPF_EXIT_INSN(),
+               },
+               .errstr_unpriv = "R1 stack pointer arithmetic goes out of range",
+               .result_unpriv = REJECT,
                .result = ACCEPT,
        },
        {
@@ -2929,6 +2986,8 @@ static struct bpf_test tests[] = {
                .fixup_prog1 = { 2 },
                .result = ACCEPT,
                .retval = 42,
+               /* Verifier rewrite for unpriv skips tail call here. */
+               .retval_unpriv = 2,
        },
        {
                "stack pointer arithmetic",
@@ -4741,6 +4800,7 @@ static struct bpf_test tests[] = {
                .fixup_cgroup_storage = { 1 },
                .result = REJECT,
                .errstr = "get_local_storage() doesn't support non-zero flags",
+               .errstr_unpriv = "R2 leaks addr into helper function",
                .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
        },
        {
@@ -7800,7 +7860,7 @@ static struct bpf_test tests[] = {
                        BPF_JMP_IMM(BPF_JA, 0, 0, -7),
                },
                .fixup_map1 = { 4 },
-               .errstr = "R0 invalid mem access 'inv'",
+               .errstr = "unbounded min value",
                .result = REJECT,
        },
        {
@@ -7881,6 +7941,7 @@ static struct bpf_test tests[] = {
                },
                .fixup_map1 = { 3 },
                .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
+               .errstr_unpriv = "R1 has unknown scalar with mixed signed bounds",
                .result = REJECT,
        },
        {
@@ -8253,6 +8314,7 @@ static struct bpf_test tests[] = {
                },
                .fixup_map1 = { 3 },
                .errstr = "pointer offset 1073741822",
+               .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range",
                .result = REJECT
        },
        {
@@ -8274,6 +8336,7 @@ static struct bpf_test tests[] = {
                },
                .fixup_map1 = { 3 },
                .errstr = "pointer offset -1073741822",
+               .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range",
                .result = REJECT
        },
        {
@@ -8445,6 +8508,7 @@ static struct bpf_test tests[] = {
                        BPF_EXIT_INSN()
                },
                .errstr = "fp pointer offset 1073741822",
+               .errstr_unpriv = "R1 stack pointer arithmetic goes out of range",
                .result = REJECT
        },
        {
@@ -9726,8 +9790,9 @@ static struct bpf_test tests[] = {
                        BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
                        BPF_EXIT_INSN(),
                },
-               .result = REJECT,
+               .errstr_unpriv = "R1 has pointer with unsupported alu operation",
                .errstr = "R0 tried to subtract pointer from scalar",
+               .result = REJECT,
        },
        {
                "check deducing bounds from const, 2",
@@ -9740,6 +9805,8 @@ static struct bpf_test tests[] = {
                        BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
                        BPF_EXIT_INSN(),
                },
+               .errstr_unpriv = "R1 has pointer with unsupported alu operation",
+               .result_unpriv = REJECT,
                .result = ACCEPT,
                .retval = 1,
        },
@@ -9751,32 +9818,37 @@ static struct bpf_test tests[] = {
                        BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
                        BPF_EXIT_INSN(),
                },
-               .result = REJECT,
+               .errstr_unpriv = "R1 has pointer with unsupported alu operation",
                .errstr = "R0 tried to subtract pointer from scalar",
+               .result = REJECT,
        },
        {
                "check deducing bounds from const, 4",
                .insns = {
+                       BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
                        BPF_MOV64_IMM(BPF_REG_0, 0),
                        BPF_JMP_IMM(BPF_JSLE, BPF_REG_0, 0, 1),
                        BPF_EXIT_INSN(),
                        BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
                        BPF_EXIT_INSN(),
-                       BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0),
+                       BPF_ALU64_REG(BPF_SUB, BPF_REG_6, BPF_REG_0),
                        BPF_EXIT_INSN(),
                },
+               .errstr_unpriv = "R6 has pointer with unsupported alu operation",
+               .result_unpriv = REJECT,
                .result = ACCEPT,
        },
        {
                "check deducing bounds from const, 5",
                .insns = {
                        BPF_MOV64_IMM(BPF_REG_0, 0),
-                       BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 1),
+                       BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 1, 1),
                        BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
                        BPF_EXIT_INSN(),
                },
-               .result = REJECT,
+               .errstr_unpriv = "R1 has pointer with unsupported alu operation",
                .errstr = "R0 tried to subtract pointer from scalar",
+               .result = REJECT,
        },
        {
                "check deducing bounds from const, 6",
@@ -9787,8 +9859,9 @@ static struct bpf_test tests[] = {
                        BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
                        BPF_EXIT_INSN(),
                },
-               .result = REJECT,
+               .errstr_unpriv = "R1 has pointer with unsupported alu operation",
                .errstr = "R0 tried to subtract pointer from scalar",
+               .result = REJECT,
        },
        {
                "check deducing bounds from const, 7",
@@ -9800,8 +9873,9 @@ static struct bpf_test tests[] = {
                                    offsetof(struct __sk_buff, mark)),
                        BPF_EXIT_INSN(),
                },
-               .result = REJECT,
+               .errstr_unpriv = "R1 has pointer with unsupported alu operation",
                .errstr = "dereference of modified ctx ptr",
+               .result = REJECT,
        },
        {
                "check deducing bounds from const, 8",
@@ -9813,8 +9887,9 @@ static struct bpf_test tests[] = {
                                    offsetof(struct __sk_buff, mark)),
                        BPF_EXIT_INSN(),
                },
-               .result = REJECT,
+               .errstr_unpriv = "R1 has pointer with unsupported alu operation",
                .errstr = "dereference of modified ctx ptr",
+               .result = REJECT,
        },
        {
                "check deducing bounds from const, 9",
@@ -9824,8 +9899,9 @@ static struct bpf_test tests[] = {
                        BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
                        BPF_EXIT_INSN(),
                },
-               .result = REJECT,
+               .errstr_unpriv = "R1 has pointer with unsupported alu operation",
                .errstr = "R0 tried to subtract pointer from scalar",
+               .result = REJECT,
        },
        {
                "check deducing bounds from const, 10",
@@ -9837,8 +9913,8 @@ static struct bpf_test tests[] = {
                        BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1),
                        BPF_EXIT_INSN(),
                },
-               .result = REJECT,
                .errstr = "math between ctx pointer and register with unbounded min value is not allowed",
+               .result = REJECT,
        },
        {
                "bpf_exit with invalid return code. test1",
@@ -12169,17 +12245,17 @@ static struct bpf_test tests[] = {
                                     BPF_FUNC_map_lookup_elem),
                        BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 28),
                        BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
-                       BPF_MOV64_IMM(BPF_REG_9, sizeof(struct test_val)),
+                       BPF_MOV64_IMM(BPF_REG_9, sizeof(struct test_val)/2),
                        BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
                        BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
-                       BPF_MOV64_IMM(BPF_REG_3, sizeof(struct test_val)),
+                       BPF_MOV64_IMM(BPF_REG_3, sizeof(struct test_val)/2),
                        BPF_MOV64_IMM(BPF_REG_4, 256),
                        BPF_EMIT_CALL(BPF_FUNC_get_stack),
                        BPF_MOV64_IMM(BPF_REG_1, 0),
                        BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
                        BPF_ALU64_IMM(BPF_LSH, BPF_REG_8, 32),
                        BPF_ALU64_IMM(BPF_ARSH, BPF_REG_8, 32),
-                       BPF_JMP_REG(BPF_JSLT, BPF_REG_1, BPF_REG_8, 16),
+                       BPF_JMP_REG(BPF_JSLT, BPF_REG_8, BPF_REG_1, 16),
                        BPF_ALU64_REG(BPF_SUB, BPF_REG_9, BPF_REG_8),
                        BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
                        BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_8),
@@ -12189,7 +12265,7 @@ static struct bpf_test tests[] = {
                        BPF_MOV64_REG(BPF_REG_3, BPF_REG_2),
                        BPF_ALU64_REG(BPF_ADD, BPF_REG_3, BPF_REG_1),
                        BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
-                       BPF_MOV64_IMM(BPF_REG_5, sizeof(struct test_val)),
+                       BPF_MOV64_IMM(BPF_REG_5, sizeof(struct test_val)/2),
                        BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_5),
                        BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 4),
                        BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
@@ -12511,6 +12587,25 @@ static struct bpf_test tests[] = {
                .prog_type = BPF_PROG_TYPE_SCHED_CLS,
                .result = ACCEPT,
        },
+       {
+               "calls: ctx read at start of subprog",
+               .insns = {
+                       BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
+                       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
+                       BPF_JMP_REG(BPF_JSGT, BPF_REG_0, BPF_REG_0, 0),
+                       BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
+                       BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
+                       BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
+                       BPF_EXIT_INSN(),
+                       BPF_LDX_MEM(BPF_B, BPF_REG_9, BPF_REG_1, 0),
+                       BPF_MOV64_IMM(BPF_REG_0, 0),
+                       BPF_EXIT_INSN(),
+               },
+               .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
+               .errstr_unpriv = "function calls to other bpf functions are allowed for root only",
+               .result_unpriv = REJECT,
+               .result = ACCEPT,
+       },
 };
 
 static int probe_filter_length(const struct bpf_insn *fp)
@@ -12536,18 +12631,18 @@ static int create_map(uint32_t type, uint32_t size_key,
        return fd;
 }
 
-static int create_prog_dummy1(void)
+static int create_prog_dummy1(enum bpf_map_type prog_type)
 {
        struct bpf_insn prog[] = {
                BPF_MOV64_IMM(BPF_REG_0, 42),
                BPF_EXIT_INSN(),
        };
 
-       return bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER, prog,
+       return bpf_load_program(prog_type, prog,
                                ARRAY_SIZE(prog), "GPL", 0, NULL, 0);
 }
 
-static int create_prog_dummy2(int mfd, int idx)
+static int create_prog_dummy2(enum bpf_map_type prog_type, int mfd, int idx)
 {
        struct bpf_insn prog[] = {
                BPF_MOV64_IMM(BPF_REG_3, idx),
@@ -12558,11 +12653,12 @@ static int create_prog_dummy2(int mfd, int idx)
                BPF_EXIT_INSN(),
        };
 
-       return bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER, prog,
+       return bpf_load_program(prog_type, prog,
                                ARRAY_SIZE(prog), "GPL", 0, NULL, 0);
 }
 
-static int create_prog_array(uint32_t max_elem, int p1key)
+static int create_prog_array(enum bpf_map_type prog_type, uint32_t max_elem,
+                            int p1key)
 {
        int p2key = 1;
        int mfd, p1fd, p2fd;
@@ -12574,8 +12670,8 @@ static int create_prog_array(uint32_t max_elem, int p1key)
                return -1;
        }
 
-       p1fd = create_prog_dummy1();
-       p2fd = create_prog_dummy2(mfd, p2key);
+       p1fd = create_prog_dummy1(prog_type);
+       p2fd = create_prog_dummy2(prog_type, mfd, p2key);
        if (p1fd < 0 || p2fd < 0)
                goto out;
        if (bpf_map_update_elem(mfd, &p1key, &p1fd, BPF_ANY) < 0)
@@ -12630,8 +12726,8 @@ static int create_cgroup_storage(void)
 
 static char bpf_vlog[UINT_MAX >> 8];
 
-static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
-                         int *map_fds)
+static void do_test_fixup(struct bpf_test *test, enum bpf_map_type prog_type,
+                         struct bpf_insn *prog, int *map_fds)
 {
        int *fixup_map1 = test->fixup_map1;
        int *fixup_map2 = test->fixup_map2;
@@ -12686,7 +12782,7 @@ static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
        }
 
        if (*fixup_prog1) {
-               map_fds[4] = create_prog_array(4, 0);
+               map_fds[4] = create_prog_array(prog_type, 4, 0);
                do {
                        prog[*fixup_prog1].imm = map_fds[4];
                        fixup_prog1++;
@@ -12694,7 +12790,7 @@ static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
        }
 
        if (*fixup_prog2) {
-               map_fds[5] = create_prog_array(8, 7);
+               map_fds[5] = create_prog_array(prog_type, 8, 7);
                do {
                        prog[*fixup_prog2].imm = map_fds[5];
                        fixup_prog2++;
@@ -12718,6 +12814,33 @@ static void do_test_fixup(struct bpf_test *test, struct bpf_insn *prog,
        }
 }
 
+static int set_admin(bool admin)
+{
+       cap_t caps;
+       const cap_value_t cap_val = CAP_SYS_ADMIN;
+       int ret = -1;
+
+       caps = cap_get_proc();
+       if (!caps) {
+               perror("cap_get_proc");
+               return -1;
+       }
+       if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_val,
+                               admin ? CAP_SET : CAP_CLEAR)) {
+               perror("cap_set_flag");
+               goto out;
+       }
+       if (cap_set_proc(caps)) {
+               perror("cap_set_proc");
+               goto out;
+       }
+       ret = 0;
+out:
+       if (cap_free(caps))
+               perror("cap_free");
+       return ret;
+}
+
 static void do_test_single(struct bpf_test *test, bool unpriv,
                           int *passes, int *errors)
 {
@@ -12726,27 +12849,32 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
        struct bpf_insn *prog = test->insns;
        int map_fds[MAX_NR_MAPS];
        const char *expected_err;
+       uint32_t expected_val;
        uint32_t retval;
        int i, err;
 
        for (i = 0; i < MAX_NR_MAPS; i++)
                map_fds[i] = -1;
 
-       do_test_fixup(test, prog, map_fds);
+       if (!prog_type)
+               prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
+       do_test_fixup(test, prog_type, prog, map_fds);
        prog_len = probe_filter_length(prog);
 
-       fd_prog = bpf_verify_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
-                                    prog, prog_len, test->flags & F_LOAD_WITH_STRICT_ALIGNMENT,
+       fd_prog = bpf_verify_program(prog_type, prog, prog_len,
+                                    test->flags & F_LOAD_WITH_STRICT_ALIGNMENT,
                                     "GPL", 0, bpf_vlog, sizeof(bpf_vlog), 1);
 
        expected_ret = unpriv && test->result_unpriv != UNDEF ?
                       test->result_unpriv : test->result;
        expected_err = unpriv && test->errstr_unpriv ?
                       test->errstr_unpriv : test->errstr;
+       expected_val = unpriv && test->retval_unpriv ?
+                      test->retval_unpriv : test->retval;
 
        reject_from_alignment = fd_prog < 0 &&
                                (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS) &&
-                               strstr(bpf_vlog, "Unknown alignment.");
+                               strstr(bpf_vlog, "misaligned");
 #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
        if (reject_from_alignment) {
                printf("FAIL\nFailed due to alignment despite having efficient unaligned access: '%s'!\n",
@@ -12776,16 +12904,20 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
                __u8 tmp[TEST_DATA_LEN << 2];
                __u32 size_tmp = sizeof(tmp);
 
+               if (unpriv)
+                       set_admin(true);
                err = bpf_prog_test_run(fd_prog, 1, test->data,
                                        sizeof(test->data), tmp, &size_tmp,
                                        &retval, NULL);
+               if (unpriv)
+                       set_admin(false);
                if (err && errno != 524/*ENOTSUPP*/ && errno != EPERM) {
                        printf("Unexpected bpf_prog_test_run error\n");
                        goto fail_log;
                }
-               if (!err && retval != test->retval &&
-                   test->retval != POINTER_VALUE) {
-                       printf("FAIL retval %d != %d\n", retval, test->retval);
+               if (!err && retval != expected_val &&
+                   expected_val != POINTER_VALUE) {
+                       printf("FAIL retval %d != %d\n", retval, expected_val);
                        goto fail_log;
                }
        }
@@ -12828,33 +12960,6 @@ static bool is_admin(void)
        return (sysadmin == CAP_SET);
 }
 
-static int set_admin(bool admin)
-{
-       cap_t caps;
-       const cap_value_t cap_val = CAP_SYS_ADMIN;
-       int ret = -1;
-
-       caps = cap_get_proc();
-       if (!caps) {
-               perror("cap_get_proc");
-               return -1;
-       }
-       if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_val,
-                               admin ? CAP_SET : CAP_CLEAR)) {
-               perror("cap_set_flag");
-               goto out;
-       }
-       if (cap_set_proc(caps)) {
-               perror("cap_set_proc");
-               goto out;
-       }
-       ret = 0;
-out:
-       if (cap_free(caps))
-               perror("cap_free");
-       return ret;
-}
-
 static void get_unpriv_disabled()
 {
        char buf[2];
@@ -12871,6 +12976,13 @@ static void get_unpriv_disabled()
        fclose(fd);
 }
 
+static bool test_as_unpriv(struct bpf_test *test)
+{
+       return !test->prog_type ||
+              test->prog_type == BPF_PROG_TYPE_SOCKET_FILTER ||
+              test->prog_type == BPF_PROG_TYPE_CGROUP_SKB;
+}
+
 static int do_test(bool unpriv, unsigned int from, unsigned int to)
 {
        int i, passes = 0, errors = 0, skips = 0;
@@ -12881,10 +12993,10 @@ static int do_test(bool unpriv, unsigned int from, unsigned int to)
                /* Program types that are not supported by non-root we
                 * skip right away.
                 */
-               if (!test->prog_type && unpriv_disabled) {
+               if (test_as_unpriv(test) && unpriv_disabled) {
                        printf("#%d/u %s SKIP\n", i, test->descr);
                        skips++;
-               } else if (!test->prog_type) {
+               } else if (test_as_unpriv(test)) {
                        if (!unpriv)
                                set_admin(false);
                        printf("#%d/u %s ", i, test->descr);