160 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Converted from tools/testing/selftests/bpf/verifier/map_ptr.c */3 4#include <linux/bpf.h>5#include <bpf/bpf_helpers.h>6#include "bpf_misc.h"7 8#define MAX_ENTRIES 119 10struct test_val {11 unsigned int index;12 int foo[MAX_ENTRIES];13};14 15struct {16 __uint(type, BPF_MAP_TYPE_ARRAY);17 __uint(max_entries, 1);18 __type(key, int);19 __type(value, struct test_val);20} map_array_48b SEC(".maps");21 22struct other_val {23 long long foo;24 long long bar;25};26 27struct {28 __uint(type, BPF_MAP_TYPE_HASH);29 __uint(max_entries, 1);30 __type(key, long long);31 __type(value, struct other_val);32} map_hash_16b SEC(".maps");33 34SEC("socket")35__description("bpf_map_ptr: read with negative offset rejected")36__failure __msg("R1 is bpf_array invalid negative access: off=-8")37__failure_unpriv38__msg_unpriv("access is allowed only to CAP_PERFMON and CAP_SYS_ADMIN")39__naked void read_with_negative_offset_rejected(void)40{41 asm volatile (" \42 r1 = r10; \43 r1 = %[map_array_48b] ll; \44 r6 = *(u64*)(r1 - 8); \45 r0 = 1; \46 exit; \47" :48 : __imm_addr(map_array_48b)49 : __clobber_all);50}51 52SEC("socket")53__description("bpf_map_ptr: write rejected")54__failure __msg("only read from bpf_array is supported")55__failure_unpriv56__msg_unpriv("access is allowed only to CAP_PERFMON and CAP_SYS_ADMIN")57__naked void bpf_map_ptr_write_rejected(void)58{59 asm volatile (" \60 r0 = 0; \61 *(u64*)(r10 - 8) = r0; \62 r2 = r10; \63 r2 += -8; \64 r1 = %[map_array_48b] ll; \65 *(u64*)(r1 + 0) = r2; \66 r0 = 1; \67 exit; \68" :69 : __imm_addr(map_array_48b)70 : __clobber_all);71}72 73SEC("socket")74__description("bpf_map_ptr: read non-existent field rejected")75__failure76__msg("cannot access ptr member ops with moff 0 in struct bpf_map with off 1 size 4")77__failure_unpriv78__msg_unpriv("access is allowed only to CAP_PERFMON and CAP_SYS_ADMIN")79__flag(BPF_F_ANY_ALIGNMENT)80__naked void read_non_existent_field_rejected(void)81{82 asm volatile (" \83 r6 = 0; \84 r1 = %[map_array_48b] ll; \85 r6 = *(u32*)(r1 + 1); \86 r0 = 1; \87 exit; \88" :89 : __imm_addr(map_array_48b)90 : __clobber_all);91}92 93SEC("socket")94__description("bpf_map_ptr: read ops field accepted")95__success __failure_unpriv96__msg_unpriv("access is allowed only to CAP_PERFMON and CAP_SYS_ADMIN")97__retval(1)98__naked void ptr_read_ops_field_accepted(void)99{100 asm volatile (" \101 r6 = 0; \102 r1 = %[map_array_48b] ll; \103 r6 = *(u64*)(r1 + 0); \104 r0 = 1; \105 exit; \106" :107 : __imm_addr(map_array_48b)108 : __clobber_all);109}110 111SEC("socket")112__description("bpf_map_ptr: r = 0, map_ptr = map_ptr + r")113__success __failure_unpriv114__msg_unpriv("R1 has pointer with unsupported alu operation")115__retval(0)116__naked void map_ptr_map_ptr_r(void)117{118 asm volatile (" \119 r0 = 0; \120 *(u64*)(r10 - 8) = r0; \121 r2 = r10; \122 r2 += -8; \123 r0 = 0; \124 r1 = %[map_hash_16b] ll; \125 r1 += r0; \126 call %[bpf_map_lookup_elem]; \127 r0 = 0; \128 exit; \129" :130 : __imm(bpf_map_lookup_elem),131 __imm_addr(map_hash_16b)132 : __clobber_all);133}134 135SEC("socket")136__description("bpf_map_ptr: r = 0, r = r + map_ptr")137__success __failure_unpriv138__msg_unpriv("R0 has pointer with unsupported alu operation")139__retval(0)140__naked void _0_r_r_map_ptr(void)141{142 asm volatile (" \143 r0 = 0; \144 *(u64*)(r10 - 8) = r0; \145 r2 = r10; \146 r2 += -8; \147 r1 = 0; \148 r0 = %[map_hash_16b] ll; \149 r1 += r0; \150 call %[bpf_map_lookup_elem]; \151 r0 = 0; \152 exit; \153" :154 : __imm(bpf_map_lookup_elem),155 __imm_addr(map_hash_16b)156 : __clobber_all);157}158 159char _license[] SEC("license") = "GPL";160