Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Test for writes to map key from BPF helpers

When invoking bpf_for_each_map_elem callback, we are passed a
PTR_TO_MAP_KEY, previously writes to this through helper may be allowed,
but the fix in previous patches is meant to prevent that case. The test
case tries to pass it as writable memory to helper, and fails test if it
succeeds to pass the verifier.

Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20220319080827.73251-6-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Kumar Kartikeya Dwivedi and committed by
Alexei Starovoitov
9fc4476a 7cb29b1c

+39
+12
tools/testing/selftests/bpf/prog_tests/for_each.c
··· 4 4 #include <network_helpers.h> 5 5 #include "for_each_hash_map_elem.skel.h" 6 6 #include "for_each_array_map_elem.skel.h" 7 + #include "for_each_map_elem_write_key.skel.h" 7 8 8 9 static unsigned int duration; 9 10 ··· 130 129 for_each_array_map_elem__destroy(skel); 131 130 } 132 131 132 + static void test_write_map_key(void) 133 + { 134 + struct for_each_map_elem_write_key *skel; 135 + 136 + skel = for_each_map_elem_write_key__open_and_load(); 137 + if (!ASSERT_ERR_PTR(skel, "for_each_map_elem_write_key__open_and_load")) 138 + for_each_map_elem_write_key__destroy(skel); 139 + } 140 + 133 141 void test_for_each(void) 134 142 { 135 143 if (test__start_subtest("hash_map")) 136 144 test_hash_map(); 137 145 if (test__start_subtest("array_map")) 138 146 test_array_map(); 147 + if (test__start_subtest("write_map_key")) 148 + test_write_map_key(); 139 149 }
+27
tools/testing/selftests/bpf/progs/for_each_map_elem_write_key.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include <vmlinux.h> 3 + #include <bpf/bpf_helpers.h> 4 + 5 + struct { 6 + __uint(type, BPF_MAP_TYPE_ARRAY); 7 + __uint(max_entries, 1); 8 + __type(key, __u32); 9 + __type(value, __u64); 10 + } array_map SEC(".maps"); 11 + 12 + static __u64 13 + check_array_elem(struct bpf_map *map, __u32 *key, __u64 *val, 14 + void *data) 15 + { 16 + bpf_get_current_comm(key, sizeof(*key)); 17 + return 0; 18 + } 19 + 20 + SEC("raw_tp/sys_enter") 21 + int test_map_key_write(const void *ctx) 22 + { 23 + bpf_for_each_map_elem(&array_map, check_array_elem, NULL, 0); 24 + return 0; 25 + } 26 + 27 + char _license[] SEC("license") = "GPL";