xref: /linux/tools/testing/selftests/bpf/prog_tests/percpu_array_inner_map.c (revision f0e77c598ebbb1ae055b156aaa33b7433ae45e51)
1 // SPDX-License-Identifier: GPL-2.0
2 #include <test_progs.h>
3 
4 /*
5  * Test that replacing an inner percpu array map with one that has different
6  * max_entries is rejected.  percpu_array_map_gen_lookup() inlines the
7  * template's index_mask, so allowing a smaller replacement would cause OOB.
8  */
test_percpu_array_inner_map(void)9 void test_percpu_array_inner_map(void)
10 {
11 	LIBBPF_OPTS(bpf_map_create_opts, opts);
12 	int outer_fd, tmpl_fd, good_fd, bad_fd, err;
13 	int zero = 0;
14 
15 	/* Create template: percpu array with 8 entries */
16 	tmpl_fd = bpf_map_create(BPF_MAP_TYPE_PERCPU_ARRAY, "tmpl",
17 				 sizeof(int), sizeof(long), 8, NULL);
18 	if (!ASSERT_OK_FD(tmpl_fd, "create_tmpl"))
19 		return;
20 
21 	/* Create outer array-of-maps using template */
22 	opts.inner_map_fd = tmpl_fd;
23 	outer_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY_OF_MAPS, "outer",
24 				  sizeof(int), sizeof(int), 1, &opts);
25 	if (!ASSERT_OK_FD(outer_fd, "create_outer"))
26 		goto close_tmpl;
27 
28 	/* Insert template as initial inner map */
29 	err = bpf_map_update_elem(outer_fd, &zero, &tmpl_fd, 0);
30 	if (!ASSERT_OK(err, "insert_tmpl"))
31 		goto close_outer;
32 
33 	/* Replacement with same max_entries should succeed */
34 	good_fd = bpf_map_create(BPF_MAP_TYPE_PERCPU_ARRAY, "good",
35 				 sizeof(int), sizeof(long), 8, NULL);
36 	if (!ASSERT_OK_FD(good_fd, "create_good"))
37 		goto close_outer;
38 
39 	err = bpf_map_update_elem(outer_fd, &zero, &good_fd, 0);
40 	ASSERT_OK(err, "replace_same_max_entries");
41 	close(good_fd);
42 
43 	/* Replacement with fewer max_entries must fail */
44 	bad_fd = bpf_map_create(BPF_MAP_TYPE_PERCPU_ARRAY, "bad",
45 				sizeof(int), sizeof(long), 2, NULL);
46 	if (!ASSERT_OK_FD(bad_fd, "create_bad"))
47 		goto close_outer;
48 
49 	err = bpf_map_update_elem(outer_fd, &zero, &bad_fd, 0);
50 	ASSERT_ERR(err, "replace_smaller_max_entries");
51 	close(bad_fd);
52 
53 close_outer:
54 	close(outer_fd);
55 close_tmpl:
56 	close(tmpl_fd);
57 }
58