Skip to content

Commit f04e49b

Browse files
fomichevKernel Patches Daemon
authored and
Kernel Patches Daemon
committed
selftests/bpf: verify lsm_cgroup struct sock access
sk_priority & sk_mark are writable, the rest is readonly. Add new ldx_offset fixups to lookup the offset of struct field. Allow using test.kfunc regardless of prog_type. One interesting thing here is that the verifier doesn't really force me to add NULL checks anywhere :-/ Signed-off-by: Stanislav Fomichev <[email protected]>
1 parent 68f7b98 commit f04e49b

File tree

2 files changed

+87
-1
lines changed

2 files changed

+87
-1
lines changed

tools/testing/selftests/bpf/test_verifier.c

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ struct kfunc_btf_id_pair {
7575
int insn_idx;
7676
};
7777

78+
struct ldx_offset {
79+
const char *strct;
80+
const char *field;
81+
int insn_idx;
82+
};
83+
7884
struct bpf_test {
7985
const char *descr;
8086
struct bpf_insn insns[MAX_INSNS];
@@ -102,6 +108,7 @@ struct bpf_test {
102108
int fixup_map_ringbuf[MAX_FIXUPS];
103109
int fixup_map_timer[MAX_FIXUPS];
104110
struct kfunc_btf_id_pair fixup_kfunc_btf_id[MAX_FIXUPS];
111+
struct ldx_offset fixup_ldx[MAX_FIXUPS];
105112
/* Expected verifier log output for result REJECT or VERBOSE_ACCEPT.
106113
* Can be a tab-separated sequence of expected strings. An empty string
107114
* means no log verification.
@@ -755,6 +762,7 @@ static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type,
755762
int *fixup_map_ringbuf = test->fixup_map_ringbuf;
756763
int *fixup_map_timer = test->fixup_map_timer;
757764
struct kfunc_btf_id_pair *fixup_kfunc_btf_id = test->fixup_kfunc_btf_id;
765+
struct ldx_offset *fixup_ldx = test->fixup_ldx;
758766

759767
if (test->fill_helper) {
760768
test->fill_insns = calloc(MAX_TEST_INSNS, sizeof(struct bpf_insn));
@@ -967,6 +975,50 @@ static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type,
967975
fixup_kfunc_btf_id++;
968976
} while (fixup_kfunc_btf_id->kfunc);
969977
}
978+
979+
if (fixup_ldx->strct) {
980+
const struct btf_member *memb;
981+
const struct btf_type *tp;
982+
const char *name;
983+
struct btf *btf;
984+
int btf_id;
985+
int off;
986+
int i;
987+
988+
btf = btf__load_vmlinux_btf();
989+
990+
do {
991+
off = -1;
992+
if (!btf)
993+
goto next_ldx;
994+
995+
btf_id = btf__find_by_name_kind(btf,
996+
fixup_ldx->strct,
997+
BTF_KIND_STRUCT);
998+
if (btf_id < 0)
999+
goto next_ldx;
1000+
1001+
tp = btf__type_by_id(btf, btf_id);
1002+
memb = btf_members(tp);
1003+
1004+
for (i = 0; i < btf_vlen(tp); i++) {
1005+
name = btf__name_by_offset(btf,
1006+
memb->name_off);
1007+
if (strcmp(fixup_ldx->field, name) == 0) {
1008+
off = memb->offset / 8;
1009+
break;
1010+
}
1011+
memb++;
1012+
}
1013+
1014+
next_ldx:
1015+
prog[fixup_ldx->insn_idx].off = off;
1016+
fixup_ldx++;
1017+
1018+
} while (fixup_ldx->strct);
1019+
1020+
btf__free(btf);
1021+
}
9701022
}
9711023

9721024
struct libcap {
@@ -1131,7 +1183,7 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
11311183
opts.log_level = 4;
11321184
opts.prog_flags = pflags;
11331185

1134-
if (prog_type == BPF_PROG_TYPE_TRACING && test->kfunc) {
1186+
if (test->kfunc) {
11351187
int attach_btf_id;
11361188

11371189
attach_btf_id = libbpf_find_vmlinux_btf_id(test->kfunc,
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#define SK_WRITABLE_FIELD(tp, field, size, res) \
2+
{ \
3+
.descr = field, \
4+
.insns = { \
5+
/* r1 = *(u64 *)(r1 + 0) */ \
6+
BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0), \
7+
/* r1 = *(u64 *)(r1 + offsetof(struct socket, sk)) */ \
8+
BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0), \
9+
/* r2 = *(u64 *)(r1 + offsetof(struct sock, <field>)) */ \
10+
BPF_LDX_MEM(size, BPF_REG_2, BPF_REG_1, 0), \
11+
/* *(u64 *)(r1 + offsetof(struct sock, <field>)) = r2 */ \
12+
BPF_STX_MEM(size, BPF_REG_1, BPF_REG_2, 0), \
13+
BPF_MOV64_IMM(BPF_REG_0, 1), \
14+
BPF_EXIT_INSN(), \
15+
}, \
16+
.result = res, \
17+
.errstr = res ? "no write support to 'struct sock' at off" : "", \
18+
.prog_type = BPF_PROG_TYPE_LSM, \
19+
.expected_attach_type = BPF_LSM_CGROUP, \
20+
.kfunc = "socket_post_create", \
21+
.fixup_ldx = { \
22+
{ "socket", "sk", 1 }, \
23+
{ tp, field, 2 }, \
24+
{ tp, field, 3 }, \
25+
}, \
26+
}
27+
28+
SK_WRITABLE_FIELD("sock_common", "skc_family", BPF_H, REJECT),
29+
SK_WRITABLE_FIELD("sock", "sk_sndtimeo", BPF_DW, REJECT),
30+
SK_WRITABLE_FIELD("sock", "sk_priority", BPF_W, ACCEPT),
31+
SK_WRITABLE_FIELD("sock", "sk_mark", BPF_W, ACCEPT),
32+
SK_WRITABLE_FIELD("sock", "sk_pacing_rate", BPF_DW, REJECT),
33+
34+
#undef SK_WRITABLE_FIELD

0 commit comments

Comments
 (0)