1 // SPDX-License-Identifier: GPL-2.0
2 /* Converted from tools/testing/selftests/bpf/verifier/leak_ptr.c */
3 
4 #include <linux/bpf.h>
5 #include <bpf/bpf_helpers.h>
6 #include "bpf_misc.h"
7 
8 struct {
9 	__uint(type, BPF_MAP_TYPE_HASH);
10 	__uint(max_entries, 1);
11 	__type(key, long long);
12 	__type(value, long long);
13 } map_hash_8b SEC(".maps");
14 
15 SEC("socket")
16 __description("leak pointer into ctx 1")
17 __failure __msg("BPF_ATOMIC stores into R1 ctx is not allowed")
18 __failure_unpriv __msg_unpriv("R2 leaks addr into mem")
leak_pointer_into_ctx_1(void)19 __naked void leak_pointer_into_ctx_1(void)
20 {
21 	asm volatile ("					\
22 	r0 = 0;						\
23 	*(u64*)(r1 + %[__sk_buff_cb_0]) = r0;		\
24 	r2 = %[map_hash_8b] ll;				\
25 	lock *(u64 *)(r1 + %[__sk_buff_cb_0]) += r2;	\
26 	exit;						\
27 "	:
28 	: __imm_addr(map_hash_8b),
29 	  __imm_const(__sk_buff_cb_0, offsetof(struct __sk_buff, cb[0]))
30 	: __clobber_all);
31 }
32 
33 SEC("socket")
34 __description("leak pointer into ctx 2")
35 __failure __msg("BPF_ATOMIC stores into R1 ctx is not allowed")
36 __failure_unpriv __msg_unpriv("R10 leaks addr into mem")
leak_pointer_into_ctx_2(void)37 __naked void leak_pointer_into_ctx_2(void)
38 {
39 	asm volatile ("					\
40 	r0 = 0;						\
41 	*(u64*)(r1 + %[__sk_buff_cb_0]) = r0;		\
42 	lock *(u64 *)(r1 + %[__sk_buff_cb_0]) += r10;	\
43 	exit;						\
44 "	:
45 	: __imm_const(__sk_buff_cb_0, offsetof(struct __sk_buff, cb[0]))
46 	: __clobber_all);
47 }
48 
49 SEC("socket")
50 __description("leak pointer into ctx 3")
51 __success __failure_unpriv __msg_unpriv("R2 leaks addr into ctx")
52 __retval(0)
leak_pointer_into_ctx_3(void)53 __naked void leak_pointer_into_ctx_3(void)
54 {
55 	asm volatile ("					\
56 	r0 = 0;						\
57 	r2 = %[map_hash_8b] ll;				\
58 	*(u64*)(r1 + %[__sk_buff_cb_0]) = r2;		\
59 	exit;						\
60 "	:
61 	: __imm_addr(map_hash_8b),
62 	  __imm_const(__sk_buff_cb_0, offsetof(struct __sk_buff, cb[0]))
63 	: __clobber_all);
64 }
65 
66 SEC("socket")
67 __description("leak pointer into map val")
68 __success __failure_unpriv __msg_unpriv("R6 leaks addr into mem")
69 __retval(0)
leak_pointer_into_map_val(void)70 __naked void leak_pointer_into_map_val(void)
71 {
72 	asm volatile ("					\
73 	r6 = r1;					\
74 	r1 = 0;						\
75 	*(u64*)(r10 - 8) = r1;				\
76 	r2 = r10;					\
77 	r2 += -8;					\
78 	r1 = %[map_hash_8b] ll;				\
79 	call %[bpf_map_lookup_elem];			\
80 	if r0 == 0 goto l0_%=;				\
81 	r3 = 0;						\
82 	*(u64*)(r0 + 0) = r3;				\
83 	lock *(u64 *)(r0 + 0) += r6;			\
84 l0_%=:	r0 = 0;						\
85 	exit;						\
86 "	:
87 	: __imm(bpf_map_lookup_elem),
88 	  __imm_addr(map_hash_8b)
89 	: __clobber_all);
90 }
91 
92 char _license[] SEC("license") = "GPL";
93