mirror of
https://github.com/torvalds/linux.git
synced 2024-11-29 23:51:37 +00:00
selftests/bpf: verifier/map_in_map converted to inline assembly
Test verifier/map_in_map automatically converted to use inline assembly. Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/r/20230421174234.2391278-12-eddyz87@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
b427ca576f
commit
4a400ef9ba
@ -34,6 +34,7 @@
|
||||
#include "verifier_leak_ptr.skel.h"
|
||||
#include "verifier_loops1.skel.h"
|
||||
#include "verifier_lwt.skel.h"
|
||||
#include "verifier_map_in_map.skel.h"
|
||||
#include "verifier_map_ptr.skel.h"
|
||||
#include "verifier_map_ret_val.skel.h"
|
||||
#include "verifier_masking.skel.h"
|
||||
@ -119,6 +120,7 @@ void test_verifier_ld_ind(void) { RUN(verifier_ld_ind); }
|
||||
void test_verifier_leak_ptr(void) { RUN(verifier_leak_ptr); }
|
||||
void test_verifier_loops1(void) { RUN(verifier_loops1); }
|
||||
void test_verifier_lwt(void) { RUN(verifier_lwt); }
|
||||
void test_verifier_map_in_map(void) { RUN(verifier_map_in_map); }
|
||||
void test_verifier_map_ptr(void) { RUN(verifier_map_ptr); }
|
||||
void test_verifier_map_ret_val(void) { RUN(verifier_map_ret_val); }
|
||||
void test_verifier_masking(void) { RUN(verifier_masking); }
|
||||
|
142
tools/testing/selftests/bpf/progs/verifier_map_in_map.c
Normal file
142
tools/testing/selftests/bpf/progs/verifier_map_in_map.c
Normal file
@ -0,0 +1,142 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Converted from tools/testing/selftests/bpf/verifier/map_in_map.c */
|
||||
|
||||
#include <linux/bpf.h>
|
||||
#include <bpf/bpf_helpers.h>
|
||||
#include "bpf_misc.h"
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
|
||||
__uint(max_entries, 1);
|
||||
__type(key, int);
|
||||
__type(value, int);
|
||||
__array(values, struct {
|
||||
__uint(type, BPF_MAP_TYPE_ARRAY);
|
||||
__uint(max_entries, 1);
|
||||
__type(key, int);
|
||||
__type(value, int);
|
||||
});
|
||||
} map_in_map SEC(".maps");
|
||||
|
||||
SEC("socket")
|
||||
__description("map in map access")
|
||||
__success __success_unpriv __retval(0)
|
||||
__naked void map_in_map_access(void)
|
||||
{
|
||||
asm volatile (" \
|
||||
r1 = 0; \
|
||||
*(u32*)(r10 - 4) = r1; \
|
||||
r2 = r10; \
|
||||
r2 += -4; \
|
||||
r1 = %[map_in_map] ll; \
|
||||
call %[bpf_map_lookup_elem]; \
|
||||
if r0 == 0 goto l0_%=; \
|
||||
r1 = 0; \
|
||||
*(u32*)(r10 - 4) = r1; \
|
||||
r2 = r10; \
|
||||
r2 += -4; \
|
||||
r1 = r0; \
|
||||
call %[bpf_map_lookup_elem]; \
|
||||
l0_%=: r0 = 0; \
|
||||
exit; \
|
||||
" :
|
||||
: __imm(bpf_map_lookup_elem),
|
||||
__imm_addr(map_in_map)
|
||||
: __clobber_all);
|
||||
}
|
||||
|
||||
SEC("xdp")
|
||||
__description("map in map state pruning")
|
||||
__success __msg("processed 26 insns")
|
||||
__log_level(2) __retval(0) __flag(BPF_F_TEST_STATE_FREQ)
|
||||
__naked void map_in_map_state_pruning(void)
|
||||
{
|
||||
asm volatile (" \
|
||||
r1 = 0; \
|
||||
*(u32*)(r10 - 4) = r1; \
|
||||
r6 = r10; \
|
||||
r6 += -4; \
|
||||
r2 = r6; \
|
||||
r1 = %[map_in_map] ll; \
|
||||
call %[bpf_map_lookup_elem]; \
|
||||
if r0 != 0 goto l0_%=; \
|
||||
exit; \
|
||||
l0_%=: r2 = r6; \
|
||||
r1 = r0; \
|
||||
call %[bpf_map_lookup_elem]; \
|
||||
if r0 != 0 goto l1_%=; \
|
||||
r2 = r6; \
|
||||
r1 = %[map_in_map] ll; \
|
||||
call %[bpf_map_lookup_elem]; \
|
||||
if r0 != 0 goto l2_%=; \
|
||||
exit; \
|
||||
l2_%=: r2 = r6; \
|
||||
r1 = r0; \
|
||||
call %[bpf_map_lookup_elem]; \
|
||||
if r0 != 0 goto l1_%=; \
|
||||
exit; \
|
||||
l1_%=: r0 = *(u32*)(r0 + 0); \
|
||||
exit; \
|
||||
" :
|
||||
: __imm(bpf_map_lookup_elem),
|
||||
__imm_addr(map_in_map)
|
||||
: __clobber_all);
|
||||
}
|
||||
|
||||
SEC("socket")
|
||||
__description("invalid inner map pointer")
|
||||
__failure __msg("R1 pointer arithmetic on map_ptr prohibited")
|
||||
__failure_unpriv
|
||||
__naked void invalid_inner_map_pointer(void)
|
||||
{
|
||||
asm volatile (" \
|
||||
r1 = 0; \
|
||||
*(u32*)(r10 - 4) = r1; \
|
||||
r2 = r10; \
|
||||
r2 += -4; \
|
||||
r1 = %[map_in_map] ll; \
|
||||
call %[bpf_map_lookup_elem]; \
|
||||
if r0 == 0 goto l0_%=; \
|
||||
r1 = 0; \
|
||||
*(u32*)(r10 - 4) = r1; \
|
||||
r2 = r10; \
|
||||
r2 += -4; \
|
||||
r1 = r0; \
|
||||
r1 += 8; \
|
||||
call %[bpf_map_lookup_elem]; \
|
||||
l0_%=: r0 = 0; \
|
||||
exit; \
|
||||
" :
|
||||
: __imm(bpf_map_lookup_elem),
|
||||
__imm_addr(map_in_map)
|
||||
: __clobber_all);
|
||||
}
|
||||
|
||||
SEC("socket")
|
||||
__description("forgot null checking on the inner map pointer")
|
||||
__failure __msg("R1 type=map_value_or_null expected=map_ptr")
|
||||
__failure_unpriv
|
||||
__naked void on_the_inner_map_pointer(void)
|
||||
{
|
||||
asm volatile (" \
|
||||
r1 = 0; \
|
||||
*(u32*)(r10 - 4) = r1; \
|
||||
r2 = r10; \
|
||||
r2 += -4; \
|
||||
r1 = %[map_in_map] ll; \
|
||||
call %[bpf_map_lookup_elem]; \
|
||||
r1 = 0; \
|
||||
*(u32*)(r10 - 4) = r1; \
|
||||
r2 = r10; \
|
||||
r2 += -4; \
|
||||
r1 = r0; \
|
||||
call %[bpf_map_lookup_elem]; \
|
||||
r0 = 0; \
|
||||
exit; \
|
||||
" :
|
||||
: __imm(bpf_map_lookup_elem),
|
||||
__imm_addr(map_in_map)
|
||||
: __clobber_all);
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
@ -1,96 +0,0 @@
|
||||
{
|
||||
"map in map access",
|
||||
.insns = {
|
||||
BPF_ST_MEM(0, BPF_REG_10, -4, 0),
|
||||
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
||||
BPF_LD_MAP_FD(BPF_REG_1, 0),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
||||
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
|
||||
BPF_ST_MEM(0, BPF_REG_10, -4, 0),
|
||||
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.fixup_map_in_map = { 3 },
|
||||
.result = ACCEPT,
|
||||
},
|
||||
{
|
||||
"map in map state pruning",
|
||||
.insns = {
|
||||
BPF_ST_MEM(0, BPF_REG_10, -4, 0),
|
||||
BPF_MOV64_REG(BPF_REG_6, BPF_REG_10),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -4),
|
||||
BPF_MOV64_REG(BPF_REG_2, BPF_REG_6),
|
||||
BPF_LD_MAP_FD(BPF_REG_1, 0),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
||||
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
||||
BPF_EXIT_INSN(),
|
||||
BPF_MOV64_REG(BPF_REG_2, BPF_REG_6),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
||||
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 11),
|
||||
BPF_MOV64_REG(BPF_REG_2, BPF_REG_6),
|
||||
BPF_LD_MAP_FD(BPF_REG_1, 0),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
||||
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
||||
BPF_EXIT_INSN(),
|
||||
BPF_MOV64_REG(BPF_REG_2, BPF_REG_6),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
||||
BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
|
||||
BPF_EXIT_INSN(),
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.fixup_map_in_map = { 4, 14 },
|
||||
.flags = BPF_F_TEST_STATE_FREQ,
|
||||
.result = VERBOSE_ACCEPT,
|
||||
.errstr = "processed 25 insns",
|
||||
.prog_type = BPF_PROG_TYPE_XDP,
|
||||
},
|
||||
{
|
||||
"invalid inner map pointer",
|
||||
.insns = {
|
||||
BPF_ST_MEM(0, BPF_REG_10, -4, 0),
|
||||
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
||||
BPF_LD_MAP_FD(BPF_REG_1, 0),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
||||
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
|
||||
BPF_ST_MEM(0, BPF_REG_10, -4, 0),
|
||||
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.fixup_map_in_map = { 3 },
|
||||
.errstr = "R1 pointer arithmetic on map_ptr prohibited",
|
||||
.result = REJECT,
|
||||
},
|
||||
{
|
||||
"forgot null checking on the inner map pointer",
|
||||
.insns = {
|
||||
BPF_ST_MEM(0, BPF_REG_10, -4, 0),
|
||||
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
||||
BPF_LD_MAP_FD(BPF_REG_1, 0),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
||||
BPF_ST_MEM(0, BPF_REG_10, -4, 0),
|
||||
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
|
||||
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
|
||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.fixup_map_in_map = { 3 },
|
||||
.errstr = "R1 type=map_value_or_null expected=map_ptr",
|
||||
.result = REJECT,
|
||||
},
|
Loading…
Reference in New Issue
Block a user