[PATCH bpf-next 2/2] selftests/bpf: Add tests for bpf_sockopt is_compat field
From: Maciej Żenczykowski <hidden>
Date: 2026-08-13 11:20:50
Also in:
bpf, lkml
Subsystem:
bpf [general] (safe dynamic programs and tools), bpf [selftests] (test runners & infrastructure), kernel selftest framework, the rest · Maintainers:
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Shuah Khan, Shuah Khan, Linus Torvalds
Sync tools/include/uapi/linux/bpf.h with the addition of the 'is_compat'
field in 'struct bpf_sockopt' and add test cases to 'prog_tests/sockopt.c'
to verify context access permissions:
- Test reading 'ctx->is_compat' in 'cgroup/{g,s}etsockopt'
(expecting 0 in native execution).
- Check verifier rejects writes to 'ctx->is_compat'
in 'cgroup/{g,s}etsockopt'.
Tested via:
tools/testing/selftests/bpf/vmtest.sh -- ./test_progs -t sockopt
Signed-off-by: Maciej Żenczykowski <redacted>
---
tools/include/uapi/linux/bpf.h | 1 +
.../selftests/bpf/prog_tests/sockopt.c | 86 +++++++++++++++++++
2 files changed, 87 insertions(+)
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index ffd96e8b920b..15f712b5b164 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h@@ -7616,6 +7616,7 @@ struct bpf_sockopt { __s32 optname; __s32 optlen; __s32 retval; + __s32 is_compat; }; struct bpf_pidns_info {
diff --git a/tools/testing/selftests/bpf/prog_tests/sockopt.c b/tools/testing/selftests/bpf/prog_tests/sockopt.c
index eaac83a7f388..c7dd22d0e3f8 100644
--- a/tools/testing/selftests/bpf/prog_tests/sockopt.c
+++ b/tools/testing/selftests/bpf/prog_tests/sockopt.c@@ -215,6 +215,49 @@ static struct sockopt_test { .get_optname = IP_TOS, .get_optlen = 1, }, + { + .descr = "getsockopt: read ctx->is_compat", + .insns = { + /* r6 = ctx->is_compat */ + BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, + offsetof(struct bpf_sockopt, is_compat)), + + /* if (ctx->is_compat == 0) { */ + BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 0, 4), + /* ctx->retval = 0 */ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, retval)), + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_JMP_A(1), + /* } else { */ + /* return 0 */ + BPF_MOV64_IMM(BPF_REG_0, 0), + /* } */ + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = BPF_CGROUP_GETSOCKOPT, + + .get_level = SOL_IP, + .get_optname = IP_TOS, + .get_optlen = 1, + }, + { + .descr = "getsockopt: deny writing to ctx->is_compat", + .insns = { + /* ctx->is_compat = 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, is_compat)), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_GETSOCKOPT, + .expected_attach_type = BPF_CGROUP_GETSOCKOPT, + + .error = DENY_LOAD, + }, { .descr = "getsockopt: deny writing to ctx->optname", .insns = {
@@ -609,6 +652,49 @@ static struct sockopt_test { .get_optval = { 1 << 3 }, .get_optlen = 1, }, + { + .descr = "setsockopt: read ctx->is_compat", + .insns = { + /* r6 = ctx->is_compat */ + BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, + offsetof(struct bpf_sockopt, is_compat)), + + /* if (ctx->is_compat == 0) { */ + BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 0, 4), + /* ctx->optlen = -1 */ + BPF_MOV64_IMM(BPF_REG_0, -1), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, optlen)), + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_JMP_A(1), + /* } else { */ + /* return 0 */ + BPF_MOV64_IMM(BPF_REG_0, 0), + /* } */ + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .set_optname = 123, + .set_optlen = 1, + .io_uring_support = true, + }, + { + .descr = "setsockopt: deny writing to ctx->is_compat", + .insns = { + /* ctx->is_compat = 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, + offsetof(struct bpf_sockopt, is_compat)), + BPF_EXIT_INSN(), + }, + .attach_type = BPF_CGROUP_SETSOCKOPT, + .expected_attach_type = BPF_CGROUP_SETSOCKOPT, + + .error = DENY_LOAD, + }, { .descr = "setsockopt: read ctx->optlen", .insns = {
--
2.55.0.691.gc56d675ccc-goog