summaryrefslogtreecommitdiffstats
path: root/tools/testing/selftests
diff options
context:
space:
mode:
authorIlya Leoshkevich <iii@linux.ibm.com>2019-10-28 08:29:02 -0400
committerAlexei Starovoitov <ast@kernel.org>2019-10-30 15:49:13 -0400
commit7541c87c9b7a7e07c84481f37f2c19063b44469b (patch)
treea1f47ae889424c14ebb736a51a075ac3ac2dd017 /tools/testing/selftests
parent050668c10047802a2b62cbf8db834c2c84042b87 (diff)
bpf: Allow narrow loads of bpf_sysctl fields with offset > 0
"ctx:file_pos sysctl:read read ok narrow" works on s390 by accident: it reads the wrong byte, which happens to have the expected value of 0. Improve the test by seeking to the 4th byte and expecting 4 instead of 0. This makes the latent problem apparent: the test attempts to read the first byte of bpf_sysctl.file_pos, assuming this is the least-significant byte, which is not the case on big-endian machines: a non-zero offset is needed. The point of the test is to verify narrow loads, so we cannot cheat our way out by simply using BPF_W. The existence of the test means that such loads have to be supported, most likely because llvm can generate them. Fix the test by adding a big-endian variant, which uses an offset to access the least-significant byte of bpf_sysctl.file_pos. This reveals the final problem: verifier rejects accesses to bpf_sysctl fields with offset > 0. Such accesses are already allowed for a wide range of structs: __sk_buff, bpf_sock_addr and sk_msg_md to name a few. Extend this support to bpf_sysctl by using bpf_ctx_range instead of offsetof when matching field offsets. Fixes: 7b146cebe30c ("bpf: Sysctl hook") Fixes: e1550bfe0de4 ("bpf: Add file_pos field to bpf_sysctl ctx") Fixes: 9a1027e52535 ("selftests/bpf: Test file_pos field in bpf_sysctl ctx") Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Andrey Ignatov <rdna@fb.com> Acked-by: Andrii Nakryiko <andriin@fb.com> Link: https://lore.kernel.org/bpf/20191028122902.9763-1-iii@linux.ibm.com
Diffstat (limited to 'tools/testing/selftests')
-rw-r--r--tools/testing/selftests/bpf/test_sysctl.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/tools/testing/selftests/bpf/test_sysctl.c b/tools/testing/selftests/bpf/test_sysctl.c
index a320e3844b17..7c6e5b173f33 100644
--- a/tools/testing/selftests/bpf/test_sysctl.c
+++ b/tools/testing/selftests/bpf/test_sysctl.c
@@ -161,9 +161,14 @@ static struct sysctl_test tests[] = {
161 .descr = "ctx:file_pos sysctl:read read ok narrow", 161 .descr = "ctx:file_pos sysctl:read read ok narrow",
162 .insns = { 162 .insns = {
163 /* If (file_pos == X) */ 163 /* If (file_pos == X) */
164#if __BYTE_ORDER == __LITTLE_ENDIAN
164 BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_1, 165 BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_1,
165 offsetof(struct bpf_sysctl, file_pos)), 166 offsetof(struct bpf_sysctl, file_pos)),
166 BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 2), 167#else
168 BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_1,
169 offsetof(struct bpf_sysctl, file_pos) + 3),
170#endif
171 BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 4, 2),
167 172
168 /* return ALLOW; */ 173 /* return ALLOW; */
169 BPF_MOV64_IMM(BPF_REG_0, 1), 174 BPF_MOV64_IMM(BPF_REG_0, 1),
@@ -176,6 +181,7 @@ static struct sysctl_test tests[] = {
176 .attach_type = BPF_CGROUP_SYSCTL, 181 .attach_type = BPF_CGROUP_SYSCTL,
177 .sysctl = "kernel/ostype", 182 .sysctl = "kernel/ostype",
178 .open_flags = O_RDONLY, 183 .open_flags = O_RDONLY,
184 .seek = 4,
179 .result = SUCCESS, 185 .result = SUCCESS,
180 }, 186 },
181 { 187 {