Skip to content

Commit c7566a6

Browse files
anakryikoAlexei Starovoitov
authored andcommitted
selftests/bpf: Add field existence CO-RE relocs tests
Add a bunch of tests validating CO-RE is handling field existence relocation. Relaxed CO-RE relocation mode is activated for these new tests to prevent libbpf from rejecting BPF object for no-match relocation, even though test BPF program is not going to use that relocation, if field is missing. Signed-off-by: Andrii Nakryiko <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 01340e3 commit c7566a6

11 files changed

+233
-2
lines changed

tools/testing/selftests/bpf/prog_tests/core_reloc.c

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,21 @@
174174
.fails = true, \
175175
}
176176

177+
#define EXISTENCE_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) { \
178+
.a = 42, \
179+
}
180+
181+
#define EXISTENCE_CASE_COMMON(name) \
182+
.case_name = #name, \
183+
.bpf_obj_file = "test_core_reloc_existence.o", \
184+
.btf_src_file = "btf__core_reloc_" #name ".o", \
185+
.relaxed_core_relocs = true \
186+
187+
#define EXISTENCE_ERR_CASE(name) { \
188+
EXISTENCE_CASE_COMMON(name), \
189+
.fails = true, \
190+
}
191+
177192
struct core_reloc_test_case {
178193
const char *case_name;
179194
const char *bpf_obj_file;
@@ -183,6 +198,7 @@ struct core_reloc_test_case {
183198
const char *output;
184199
int output_len;
185200
bool fails;
201+
bool relaxed_core_relocs;
186202
};
187203

188204
static struct core_reloc_test_case test_cases[] = {
@@ -283,6 +299,59 @@ static struct core_reloc_test_case test_cases[] = {
283299
},
284300
.output_len = sizeof(struct core_reloc_misc_output),
285301
},
302+
303+
/* validate field existence checks */
304+
{
305+
EXISTENCE_CASE_COMMON(existence),
306+
.input = STRUCT_TO_CHAR_PTR(core_reloc_existence) {
307+
.a = 1,
308+
.b = 2,
309+
.c = 3,
310+
.arr = { 4 },
311+
.s = { .x = 5 },
312+
},
313+
.input_len = sizeof(struct core_reloc_existence),
314+
.output = STRUCT_TO_CHAR_PTR(core_reloc_existence_output) {
315+
.a_exists = 1,
316+
.b_exists = 1,
317+
.c_exists = 1,
318+
.arr_exists = 1,
319+
.s_exists = 1,
320+
.a_value = 1,
321+
.b_value = 2,
322+
.c_value = 3,
323+
.arr_value = 4,
324+
.s_value = 5,
325+
},
326+
.output_len = sizeof(struct core_reloc_existence_output),
327+
},
328+
{
329+
EXISTENCE_CASE_COMMON(existence___minimal),
330+
.input = STRUCT_TO_CHAR_PTR(core_reloc_existence___minimal) {
331+
.a = 42,
332+
},
333+
.input_len = sizeof(struct core_reloc_existence),
334+
.output = STRUCT_TO_CHAR_PTR(core_reloc_existence_output) {
335+
.a_exists = 1,
336+
.b_exists = 0,
337+
.c_exists = 0,
338+
.arr_exists = 0,
339+
.s_exists = 0,
340+
.a_value = 42,
341+
.b_value = 0xff000002u,
342+
.c_value = 0xff000003u,
343+
.arr_value = 0xff000004u,
344+
.s_value = 0xff000005u,
345+
},
346+
.output_len = sizeof(struct core_reloc_existence_output),
347+
},
348+
349+
EXISTENCE_ERR_CASE(existence__err_int_sz),
350+
EXISTENCE_ERR_CASE(existence__err_int_type),
351+
EXISTENCE_ERR_CASE(existence__err_int_kind),
352+
EXISTENCE_ERR_CASE(existence__err_arr_kind),
353+
EXISTENCE_ERR_CASE(existence__err_arr_value_type),
354+
EXISTENCE_ERR_CASE(existence__err_struct_type),
286355
};
287356

288357
struct data {
@@ -305,11 +374,14 @@ void test_core_reloc(void)
305374

306375
for (i = 0; i < ARRAY_SIZE(test_cases); i++) {
307376
test_case = &test_cases[i];
308-
309377
if (!test__start_subtest(test_case->case_name))
310378
continue;
311379

312-
obj = bpf_object__open(test_case->bpf_obj_file);
380+
LIBBPF_OPTS(bpf_object_open_opts, opts,
381+
.relaxed_core_relocs = test_case->relaxed_core_relocs,
382+
);
383+
384+
obj = bpf_object__open_file(test_case->bpf_obj_file, &opts);
313385
if (CHECK(IS_ERR_OR_NULL(obj), "obj_open",
314386
"failed to open '%s': %ld\n",
315387
test_case->bpf_obj_file, PTR_ERR(obj)))
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "core_reloc_types.h"
2+
3+
void f(struct core_reloc_existence x) {}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "core_reloc_types.h"
2+
3+
void f(struct core_reloc_existence___err_wrong_arr_kind x) {}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "core_reloc_types.h"
2+
3+
void f(struct core_reloc_existence___err_wrong_arr_value_type x) {}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "core_reloc_types.h"
2+
3+
void f(struct core_reloc_existence___err_wrong_int_kind x) {}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "core_reloc_types.h"
2+
3+
void f(struct core_reloc_existence___err_wrong_int_sz x) {}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "core_reloc_types.h"
2+
3+
void f(struct core_reloc_existence___err_wrong_int_type x) {}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "core_reloc_types.h"
2+
3+
void f(struct core_reloc_existence___err_wrong_struct_type x) {}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "core_reloc_types.h"
2+
3+
void f(struct core_reloc_existence___minimal x) {}

tools/testing/selftests/bpf/progs/core_reloc_types.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,3 +674,59 @@ struct core_reloc_misc_extensible {
674674
int c;
675675
int d;
676676
};
677+
678+
/*
679+
* EXISTENCE
680+
*/
681+
struct core_reloc_existence_output {
682+
int a_exists;
683+
int a_value;
684+
int b_exists;
685+
int b_value;
686+
int c_exists;
687+
int c_value;
688+
int arr_exists;
689+
int arr_value;
690+
int s_exists;
691+
int s_value;
692+
};
693+
694+
struct core_reloc_existence {
695+
int a;
696+
struct {
697+
int b;
698+
};
699+
int c;
700+
int arr[1];
701+
struct {
702+
int x;
703+
} s;
704+
};
705+
706+
struct core_reloc_existence___minimal {
707+
int a;
708+
};
709+
710+
struct core_reloc_existence___err_wrong_int_sz {
711+
short a;
712+
};
713+
714+
struct core_reloc_existence___err_wrong_int_type {
715+
int b[1];
716+
};
717+
718+
struct core_reloc_existence___err_wrong_int_kind {
719+
struct{ int x; } c;
720+
};
721+
722+
struct core_reloc_existence___err_wrong_arr_kind {
723+
int arr;
724+
};
725+
726+
struct core_reloc_existence___err_wrong_arr_value_type {
727+
short arr[1];
728+
};
729+
730+
struct core_reloc_existence___err_wrong_struct_type {
731+
int s;
732+
};
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
// Copyright (c) 2019 Facebook
3+
4+
#include <linux/bpf.h>
5+
#include <stdint.h>
6+
#include "bpf_helpers.h"
7+
#include "bpf_core_read.h"
8+
9+
char _license[] SEC("license") = "GPL";
10+
11+
static volatile struct data {
12+
char in[256];
13+
char out[256];
14+
} data;
15+
16+
struct core_reloc_existence_output {
17+
int a_exists;
18+
int a_value;
19+
int b_exists;
20+
int b_value;
21+
int c_exists;
22+
int c_value;
23+
int arr_exists;
24+
int arr_value;
25+
int s_exists;
26+
int s_value;
27+
};
28+
29+
struct core_reloc_existence {
30+
struct {
31+
int x;
32+
} s;
33+
int arr[1];
34+
int a;
35+
struct {
36+
int b;
37+
};
38+
int c;
39+
};
40+
41+
SEC("raw_tracepoint/sys_enter")
42+
int test_core_existence(void *ctx)
43+
{
44+
struct core_reloc_existence *in = (void *)&data.in;
45+
struct core_reloc_existence_output *out = (void *)&data.out;
46+
47+
out->a_exists = bpf_core_field_exists(in->a);
48+
if (bpf_core_field_exists(in->a))
49+
out->a_value = BPF_CORE_READ(in, a);
50+
else
51+
out->a_value = 0xff000001u;
52+
53+
out->b_exists = bpf_core_field_exists(in->b);
54+
if (bpf_core_field_exists(in->b))
55+
out->b_value = BPF_CORE_READ(in, b);
56+
else
57+
out->b_value = 0xff000002u;
58+
59+
out->c_exists = bpf_core_field_exists(in->c);
60+
if (bpf_core_field_exists(in->c))
61+
out->c_value = BPF_CORE_READ(in, c);
62+
else
63+
out->c_value = 0xff000003u;
64+
65+
out->arr_exists = bpf_core_field_exists(in->arr);
66+
if (bpf_core_field_exists(in->arr))
67+
out->arr_value = BPF_CORE_READ(in, arr[0]);
68+
else
69+
out->arr_value = 0xff000004u;
70+
71+
out->s_exists = bpf_core_field_exists(in->s);
72+
if (bpf_core_field_exists(in->s))
73+
out->s_value = BPF_CORE_READ(in, s.x);
74+
else
75+
out->s_value = 0xff000005u;
76+
77+
return 0;
78+
}
79+

0 commit comments

Comments
 (0)