1 // SPDX-License-Identifier: GPL-2.0 2 #include <test_progs.h> 3 4 static void test_global_data_number(struct bpf_object *obj, __u32 duration) 5 { 6 int i, err, map_fd; 7 uint64_t num; 8 9 map_fd = bpf_find_map(__func__, obj, "result_number"); 10 if (CHECK_FAIL(map_fd < 0)) 11 return; 12 13 struct { 14 char *name; 15 uint32_t key; 16 uint64_t num; 17 } tests[] = { 18 { "relocate .bss reference", 0, 0 }, 19 { "relocate .data reference", 1, 42 }, 20 { "relocate .rodata reference", 2, 24 }, 21 { "relocate .bss reference", 3, 0 }, 22 { "relocate .data reference", 4, 0xffeeff }, 23 { "relocate .rodata reference", 5, 0xabab }, 24 { "relocate .bss reference", 6, 1234 }, 25 { "relocate .bss reference", 7, 0 }, 26 { "relocate .rodata reference", 8, 0xab }, 27 { "relocate .rodata reference", 9, 0x1111111111111111 }, 28 { "relocate .rodata reference", 10, ~0 }, 29 }; 30 31 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { 32 err = bpf_map_lookup_elem(map_fd, &tests[i].key, &num); 33 CHECK(err || num != tests[i].num, tests[i].name, 34 "err %d result %lx expected %lx\n", 35 err, num, tests[i].num); 36 } 37 } 38 39 static void test_global_data_string(struct bpf_object *obj, __u32 duration) 40 { 41 int i, err, map_fd; 42 char str[32]; 43 44 map_fd = bpf_find_map(__func__, obj, "result_string"); 45 if (CHECK_FAIL(map_fd < 0)) 46 return; 47 48 struct { 49 char *name; 50 uint32_t key; 51 char str[32]; 52 } tests[] = { 53 { "relocate .rodata reference", 0, "abcdefghijklmnopqrstuvwxyz" }, 54 { "relocate .data reference", 1, "abcdefghijklmnopqrstuvwxyz" }, 55 { "relocate .bss reference", 2, "" }, 56 { "relocate .data reference", 3, "abcdexghijklmnopqrstuvwxyz" }, 57 { "relocate .bss reference", 4, "\0\0hello" }, 58 }; 59 60 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { 61 err = bpf_map_lookup_elem(map_fd, &tests[i].key, str); 62 CHECK(err || memcmp(str, tests[i].str, sizeof(str)), 63 tests[i].name, "err %d result \'%s\' expected \'%s\'\n", 64 err, str, tests[i].str); 65 } 66 } 67 68 struct foo { 69 __u8 a; 70 __u32 b; 71 __u64 c; 72 }; 73 74 static void test_global_data_struct(struct bpf_object *obj, __u32 duration) 75 { 76 int i, err, map_fd; 77 struct foo val; 78 79 map_fd = bpf_find_map(__func__, obj, "result_struct"); 80 if (CHECK_FAIL(map_fd < 0)) 81 return; 82 83 struct { 84 char *name; 85 uint32_t key; 86 struct foo val; 87 } tests[] = { 88 { "relocate .rodata reference", 0, { 42, 0xfefeefef, 0x1111111111111111ULL, } }, 89 { "relocate .bss reference", 1, { } }, 90 { "relocate .rodata reference", 2, { } }, 91 { "relocate .data reference", 3, { 41, 0xeeeeefef, 0x2111111111111111ULL, } }, 92 }; 93 94 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { 95 err = bpf_map_lookup_elem(map_fd, &tests[i].key, &val); 96 CHECK(err || memcmp(&val, &tests[i].val, sizeof(val)), 97 tests[i].name, "err %d result { %u, %u, %llu } expected { %u, %u, %llu }\n", 98 err, val.a, val.b, val.c, tests[i].val.a, tests[i].val.b, tests[i].val.c); 99 } 100 } 101 102 static void test_global_data_rdonly(struct bpf_object *obj, __u32 duration) 103 { 104 int err = -ENOMEM, map_fd, zero = 0; 105 struct bpf_map *map; 106 __u8 *buff; 107 108 map = bpf_object__find_map_by_name(obj, "test_glo.rodata"); 109 if (CHECK_FAIL(!map || !bpf_map__is_internal(map))) 110 return; 111 112 map_fd = bpf_map__fd(map); 113 if (CHECK_FAIL(map_fd < 0)) 114 return; 115 116 buff = malloc(bpf_map__def(map)->value_size); 117 if (buff) 118 err = bpf_map_update_elem(map_fd, &zero, buff, 0); 119 free(buff); 120 CHECK(!err || errno != EPERM, "test .rodata read-only map", 121 "err %d errno %d\n", err, errno); 122 } 123 124 void test_global_data(void) 125 { 126 const char *file = "./test_global_data.o"; 127 __u32 duration = 0, retval; 128 struct bpf_object *obj; 129 int err, prog_fd; 130 131 err = bpf_prog_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd); 132 if (CHECK(err, "load program", "error %d loading %s\n", err, file)) 133 return; 134 135 err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), 136 NULL, NULL, &retval, &duration); 137 CHECK(err || retval, "pass global data run", 138 "err %d errno %d retval %d duration %d\n", 139 err, errno, retval, duration); 140 141 test_global_data_number(obj, duration); 142 test_global_data_string(obj, duration); 143 test_global_data_struct(obj, duration); 144 test_global_data_rdonly(obj, duration); 145 146 bpf_object__close(obj); 147 } 148