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

selftests/bpf: test instructions arrays with blinding

Add a specific test for instructions arrays with blinding enabled.

Signed-off-by: Anton Protopopov <a.s.protopopov@gmail.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20251105090410.1250500-7-a.s.protopopov@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Anton Protopopov and committed by
Alexei Starovoitov
ae48162a 30ec0ec0

+95
+95
tools/testing/selftests/bpf/prog_tests/bpf_insn_array.c
··· 227 227 check_mid_insn_index(); 228 228 } 229 229 230 + static int set_bpf_jit_harden(char *level) 231 + { 232 + char old_level; 233 + int err = -1; 234 + int fd = -1; 235 + 236 + fd = open("/proc/sys/net/core/bpf_jit_harden", O_RDWR | O_NONBLOCK); 237 + if (fd < 0) { 238 + ASSERT_FAIL("open .../bpf_jit_harden returned %d (errno=%d)", fd, errno); 239 + return -1; 240 + } 241 + 242 + err = read(fd, &old_level, 1); 243 + if (err != 1) { 244 + ASSERT_FAIL("read from .../bpf_jit_harden returned %d (errno=%d)", err, errno); 245 + err = -1; 246 + goto end; 247 + } 248 + 249 + lseek(fd, 0, SEEK_SET); 250 + 251 + err = write(fd, level, 1); 252 + if (err != 1) { 253 + ASSERT_FAIL("write to .../bpf_jit_harden returned %d (errno=%d)", err, errno); 254 + err = -1; 255 + goto end; 256 + } 257 + 258 + err = 0; 259 + *level = old_level; 260 + end: 261 + if (fd >= 0) 262 + close(fd); 263 + return err; 264 + } 265 + 266 + static void check_blindness(void) 267 + { 268 + struct bpf_insn insns[] = { 269 + BPF_MOV64_IMM(BPF_REG_0, 4), 270 + BPF_MOV64_IMM(BPF_REG_0, 3), 271 + BPF_MOV64_IMM(BPF_REG_0, 2), 272 + BPF_MOV64_IMM(BPF_REG_0, 1), 273 + BPF_EXIT_INSN(), 274 + }; 275 + int prog_fd = -1, map_fd; 276 + struct bpf_insn_array_value val = {}; 277 + char bpf_jit_harden = '@'; /* non-exizsting value */ 278 + int i; 279 + 280 + map_fd = map_create(BPF_MAP_TYPE_INSN_ARRAY, ARRAY_SIZE(insns)); 281 + if (!ASSERT_GE(map_fd, 0, "map_create")) 282 + return; 283 + 284 + for (i = 0; i < ARRAY_SIZE(insns); i++) { 285 + val.orig_off = i; 286 + if (!ASSERT_EQ(bpf_map_update_elem(map_fd, &i, &val, 0), 0, "bpf_map_update_elem")) 287 + goto cleanup; 288 + } 289 + 290 + if (!ASSERT_EQ(bpf_map_freeze(map_fd), 0, "bpf_map_freeze")) 291 + goto cleanup; 292 + 293 + bpf_jit_harden = '2'; 294 + if (set_bpf_jit_harden(&bpf_jit_harden)) { 295 + bpf_jit_harden = '@'; /* open, read or write failed => no write was done */ 296 + goto cleanup; 297 + } 298 + 299 + prog_fd = prog_load(insns, ARRAY_SIZE(insns), &map_fd, 1); 300 + if (!ASSERT_GE(prog_fd, 0, "bpf(BPF_PROG_LOAD)")) 301 + goto cleanup; 302 + 303 + for (i = 0; i < ARRAY_SIZE(insns); i++) { 304 + char fmt[32]; 305 + 306 + if (!ASSERT_EQ(bpf_map_lookup_elem(map_fd, &i, &val), 0, "bpf_map_lookup_elem")) 307 + goto cleanup; 308 + 309 + snprintf(fmt, sizeof(fmt), "val should be equal 3*%d", i); 310 + ASSERT_EQ(val.xlated_off, i * 3, fmt); 311 + } 312 + 313 + cleanup: 314 + /* restore the old one */ 315 + if (bpf_jit_harden != '@') 316 + set_bpf_jit_harden(&bpf_jit_harden); 317 + 318 + close(prog_fd); 319 + close(map_fd); 320 + } 321 + 230 322 /* Once map was initialized, it should be frozen */ 231 323 static void check_load_unfrozen_map(void) 232 324 { ··· 473 381 474 382 if (test__start_subtest("deletions-with-functions")) 475 383 check_deletions_with_functions(); 384 + 385 + if (test__start_subtest("blindness")) 386 + check_blindness(); 476 387 477 388 /* Check all kinds of operations and related restrictions */ 478 389