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

selftests/bpf: Add flexible array relocation tests

Add few tests validation CO-RE relocation handling of flexible array accesses.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20191215070844.1014385-3-andriin@fb.com

authored by

Andrii Nakryiko and committed by
Alexei Starovoitov
5f2eecef 1b484b30

+56 -4
+4
tools/testing/selftests/bpf/prog_tests/core_reloc.c
··· 74 74 .b123 = 2, \ 75 75 .c1c = 3, \ 76 76 .d00d = 4, \ 77 + .f10c = 0, \ 77 78 }, \ 78 79 .output_len = sizeof(struct core_reloc_arrays_output) \ 79 80 } ··· 309 308 ARRAYS_CASE(arrays), 310 309 ARRAYS_CASE(arrays___diff_arr_dim), 311 310 ARRAYS_CASE(arrays___diff_arr_val_sz), 311 + ARRAYS_CASE(arrays___equiv_zero_sz_arr), 312 + ARRAYS_CASE(arrays___fixed_arr), 312 313 313 314 ARRAYS_ERR_CASE(arrays___err_too_small), 314 315 ARRAYS_ERR_CASE(arrays___err_too_shallow), 315 316 ARRAYS_ERR_CASE(arrays___err_non_array), 316 317 ARRAYS_ERR_CASE(arrays___err_wrong_val_type1), 317 318 ARRAYS_ERR_CASE(arrays___err_wrong_val_type2), 319 + ARRAYS_ERR_CASE(arrays___err_bad_zero_sz_arr), 318 320 319 321 /* enum/ptr/int handling scenarios */ 320 322 PRIMITIVES_CASE(primitives),
+3
tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___equiv_zero_sz_arr.c
··· 1 + #include "core_reloc_types.h" 2 + 3 + void f(struct core_reloc_arrays___equiv_zero_sz_arr x) {}
+3
tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___err_bad_zero_sz_arr.c
··· 1 + #include "core_reloc_types.h" 2 + 3 + void f(struct core_reloc_arrays___err_bad_zero_sz_arr x) {}
+3
tools/testing/selftests/bpf/progs/btf__core_reloc_arrays___fixed_arr.c
··· 1 + #include "core_reloc_types.h" 2 + 3 + void f(struct core_reloc_arrays___fixed_arr x) {}
+39
tools/testing/selftests/bpf/progs/core_reloc_types.h
··· 327 327 char b123; 328 328 int c1c; 329 329 int d00d; 330 + int f10c; 330 331 }; 331 332 332 333 struct core_reloc_arrays_substruct { ··· 340 339 char b[2][3][4]; 341 340 struct core_reloc_arrays_substruct c[3]; 342 341 struct core_reloc_arrays_substruct d[1][2]; 342 + struct core_reloc_arrays_substruct f[][2]; 343 343 }; 344 344 345 345 /* bigger array dimensions */ ··· 349 347 char b[3][4][5]; 350 348 struct core_reloc_arrays_substruct c[4]; 351 349 struct core_reloc_arrays_substruct d[2][3]; 350 + struct core_reloc_arrays_substruct f[1][3]; 352 351 }; 353 352 354 353 /* different size of array's value (struct) */ ··· 366 363 int d; 367 364 int __padding2; 368 365 } d[1][2]; 366 + struct { 367 + int __padding1; 368 + int c; 369 + int __padding2; 370 + } f[][2]; 371 + }; 372 + 373 + struct core_reloc_arrays___equiv_zero_sz_arr { 374 + int a[5]; 375 + char b[2][3][4]; 376 + struct core_reloc_arrays_substruct c[3]; 377 + struct core_reloc_arrays_substruct d[1][2]; 378 + /* equivalent to flexible array */ 379 + struct core_reloc_arrays_substruct f[0][2]; 380 + }; 381 + 382 + struct core_reloc_arrays___fixed_arr { 383 + int a[5]; 384 + char b[2][3][4]; 385 + struct core_reloc_arrays_substruct c[3]; 386 + struct core_reloc_arrays_substruct d[1][2]; 387 + /* not a flexible array anymore, but within access bounds */ 388 + struct core_reloc_arrays_substruct f[1][2]; 369 389 }; 370 390 371 391 struct core_reloc_arrays___err_too_small { ··· 396 370 char b[2][3][4]; 397 371 struct core_reloc_arrays_substruct c[3]; 398 372 struct core_reloc_arrays_substruct d[1][2]; 373 + struct core_reloc_arrays_substruct f[][2]; 399 374 }; 400 375 401 376 struct core_reloc_arrays___err_too_shallow { ··· 404 377 char b[2][3]; /* this one lacks one dimension */ 405 378 struct core_reloc_arrays_substruct c[3]; 406 379 struct core_reloc_arrays_substruct d[1][2]; 380 + struct core_reloc_arrays_substruct f[][2]; 407 381 }; 408 382 409 383 struct core_reloc_arrays___err_non_array { ··· 412 384 char b[2][3][4]; 413 385 struct core_reloc_arrays_substruct c[3]; 414 386 struct core_reloc_arrays_substruct d[1][2]; 387 + struct core_reloc_arrays_substruct f[][2]; 415 388 }; 416 389 417 390 struct core_reloc_arrays___err_wrong_val_type { 418 391 int a[5]; 419 392 char b[2][3][4]; 420 393 int c[3]; /* value is not a struct */ 394 + struct core_reloc_arrays_substruct d[1][2]; 395 + struct core_reloc_arrays_substruct f[][2]; 396 + }; 397 + 398 + struct core_reloc_arrays___err_bad_zero_sz_arr { 399 + /* zero-sized array, but not at the end */ 400 + struct core_reloc_arrays_substruct f[0][2]; 401 + int a[5]; 402 + char b[2][3][4]; 403 + struct core_reloc_arrays_substruct c[3]; 421 404 struct core_reloc_arrays_substruct d[1][2]; 422 405 }; 423 406
+4 -4
tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c
··· 18 18 char b123; 19 19 int c1c; 20 20 int d00d; 21 + int f01c; 21 22 }; 22 23 23 24 struct core_reloc_arrays_substruct { ··· 31 30 char b[2][3][4]; 32 31 struct core_reloc_arrays_substruct c[3]; 33 32 struct core_reloc_arrays_substruct d[1][2]; 33 + struct core_reloc_arrays_substruct f[][2]; 34 34 }; 35 35 36 36 #define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*(dst)), src) ··· 42 40 struct core_reloc_arrays *in = (void *)&data.in; 43 41 struct core_reloc_arrays_output *out = (void *)&data.out; 44 42 45 - /* in->a[2] */ 46 43 if (CORE_READ(&out->a2, &in->a[2])) 47 44 return 1; 48 - /* in->b[1][2][3] */ 49 45 if (CORE_READ(&out->b123, &in->b[1][2][3])) 50 46 return 1; 51 - /* in->c[1].c */ 52 47 if (CORE_READ(&out->c1c, &in->c[1].c)) 53 48 return 1; 54 - /* in->d[0][0].d */ 55 49 if (CORE_READ(&out->d00d, &in->d[0][0].d)) 50 + return 1; 51 + if (CORE_READ(&out->f01c, &in->f[0][1].c)) 56 52 return 1; 57 53 58 54 return 0;