Add a test that reads the two u64 fields bytes_received and bytes_acked
at offset + 4 with a u32 load, to make sure such a narrower access is
rejected with "invalid tcp_sock access".

Signed-off-by: Jiayuan Chen <[email protected]>
---
 .../selftests/bpf/progs/verifier_sock.c       | 48 +++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/tools/testing/selftests/bpf/progs/verifier_sock.c 
b/tools/testing/selftests/bpf/progs/verifier_sock.c
index 565c4d8bc3fa..d8e65938c35c 100644
--- a/tools/testing/selftests/bpf/progs/verifier_sock.c
+++ b/tools/testing/selftests/bpf/progs/verifier_sock.c
@@ -611,6 +611,54 @@ l1_%=:     r0 = *(u64*)(r0 + 
%[bpf_tcp_sock_bytes_acked__end]);\
        : __clobber_all);
 }
 
+SEC("cgroup/skb")
+__description("bpf_tcp_sock(skb->sk): narrow load of tp->bytes_received")
+__failure __msg("invalid tcp_sock access")
+__failure_unpriv
+__naked void skb_sk_tp_bytes_received_narrow(void)
+{
+       asm volatile ("                                 \
+       r1 = *(u64*)(r1 + %[__sk_buff_sk]);             \
+       if r1 != 0 goto l0_%=;                          \
+       r0 = 0;                                         \
+       exit;                                           \
+l0_%=: call %[bpf_tcp_sock];                           \
+       if r0 != 0 goto l1_%=;                          \
+       exit;                                           \
+l1_%=: r0 = *(u32*)(r0 + %[off]);                      \
+       r0 = 0;                                         \
+       exit;                                           \
+"      :
+       : __imm(bpf_tcp_sock),
+         __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),
+         __imm_const(off, offsetof(struct bpf_tcp_sock, bytes_received) + 4)
+       : __clobber_all);
+}
+
+SEC("cgroup/skb")
+__description("bpf_tcp_sock(skb->sk): narrow load of tp->bytes_acked")
+__failure __msg("invalid tcp_sock access")
+__failure_unpriv
+__naked void skb_sk_tp_bytes_acked_narrow(void)
+{
+       asm volatile ("                                 \
+       r1 = *(u64*)(r1 + %[__sk_buff_sk]);             \
+       if r1 != 0 goto l0_%=;                          \
+       r0 = 0;                                         \
+       exit;                                           \
+l0_%=: call %[bpf_tcp_sock];                           \
+       if r0 != 0 goto l1_%=;                          \
+       exit;                                           \
+l1_%=: r0 = *(u32*)(r0 + %[off]);                      \
+       r0 = 0;                                         \
+       exit;                                           \
+"      :
+       : __imm(bpf_tcp_sock),
+         __imm_const(__sk_buff_sk, offsetof(struct __sk_buff, sk)),
+         __imm_const(off, offsetof(struct bpf_tcp_sock, bytes_acked) + 4)
+       : __clobber_all);
+}
+
 SEC("cgroup/skb")
 __description("bpf_tcp_sock(bpf_sk_fullsock(skb->sk)): tp->snd_cwnd")
 __success __success_unpriv __retval(0)
-- 
2.43.0


Reply via email to