Loading...
Note: File does not exist in v6.9.4.
1{
2 /* This is equivalent to the following program:
3 *
4 * r6 = skb->sk;
5 * r7 = sk_fullsock(r6);
6 * r0 = sk_fullsock(r6);
7 * if (r0 == 0) return 0; (a)
8 * if (r0 != r7) return 0; (b)
9 * *r7->type; (c)
10 * return 0;
11 *
12 * It is safe to dereference r7 at point (c), because of (a) and (b).
13 * The test verifies that relation r0 == r7 is propagated from (b) to (c).
14 */
15 "jne/jeq infer not null, PTR_TO_SOCKET_OR_NULL -> PTR_TO_SOCKET for JNE false branch",
16 .insns = {
17 /* r6 = skb->sk; */
18 BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, offsetof(struct __sk_buff, sk)),
19 /* if (r6 == 0) return 0; */
20 BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 8),
21 /* r7 = sk_fullsock(skb); */
22 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
23 BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
24 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
25 /* r0 = sk_fullsock(skb); */
26 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
27 BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
28 /* if (r0 == null) return 0; */
29 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
30 /* if (r0 == r7) r0 = *(r7->type); */
31 BPF_JMP_REG(BPF_JNE, BPF_REG_0, BPF_REG_7, 1), /* Use ! JNE ! */
32 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_7, offsetof(struct bpf_sock, type)),
33 /* return 0 */
34 BPF_MOV64_IMM(BPF_REG_0, 0),
35 BPF_EXIT_INSN(),
36 },
37 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
38 .result = ACCEPT,
39 .result_unpriv = REJECT,
40 .errstr_unpriv = "R7 pointer comparison",
41},
42{
43 /* Same as above, but verify that another branch of JNE still
44 * prohibits access to PTR_MAYBE_NULL.
45 */
46 "jne/jeq infer not null, PTR_TO_SOCKET_OR_NULL unchanged for JNE true branch",
47 .insns = {
48 /* r6 = skb->sk */
49 BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, offsetof(struct __sk_buff, sk)),
50 /* if (r6 == 0) return 0; */
51 BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 9),
52 /* r7 = sk_fullsock(skb); */
53 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
54 BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
55 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
56 /* r0 = sk_fullsock(skb); */
57 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
58 BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
59 /* if (r0 == null) return 0; */
60 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3),
61 /* if (r0 == r7) return 0; */
62 BPF_JMP_REG(BPF_JNE, BPF_REG_0, BPF_REG_7, 1), /* Use ! JNE ! */
63 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
64 /* r0 = *(r7->type); */
65 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_7, offsetof(struct bpf_sock, type)),
66 /* return 0 */
67 BPF_MOV64_IMM(BPF_REG_0, 0),
68 BPF_EXIT_INSN(),
69 },
70 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
71 .result = REJECT,
72 .errstr = "R7 invalid mem access 'sock_or_null'",
73 .result_unpriv = REJECT,
74 .errstr_unpriv = "R7 pointer comparison",
75},
76{
77 /* Same as a first test, but not null should be inferred for JEQ branch */
78 "jne/jeq infer not null, PTR_TO_SOCKET_OR_NULL -> PTR_TO_SOCKET for JEQ true branch",
79 .insns = {
80 /* r6 = skb->sk; */
81 BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, offsetof(struct __sk_buff, sk)),
82 /* if (r6 == null) return 0; */
83 BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 9),
84 /* r7 = sk_fullsock(skb); */
85 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
86 BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
87 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
88 /* r0 = sk_fullsock(skb); */
89 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
90 BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
91 /* if (r0 == null) return 0; */
92 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
93 /* if (r0 != r7) return 0; */
94 BPF_JMP_REG(BPF_JEQ, BPF_REG_0, BPF_REG_7, 1), /* Use ! JEQ ! */
95 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
96 /* r0 = *(r7->type); */
97 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_7, offsetof(struct bpf_sock, type)),
98 /* return 0; */
99 BPF_MOV64_IMM(BPF_REG_0, 0),
100 BPF_EXIT_INSN(),
101 },
102 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
103 .result = ACCEPT,
104 .result_unpriv = REJECT,
105 .errstr_unpriv = "R7 pointer comparison",
106},
107{
108 /* Same as above, but verify that another branch of JNE still
109 * prohibits access to PTR_MAYBE_NULL.
110 */
111 "jne/jeq infer not null, PTR_TO_SOCKET_OR_NULL unchanged for JEQ false branch",
112 .insns = {
113 /* r6 = skb->sk; */
114 BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, offsetof(struct __sk_buff, sk)),
115 /* if (r6 == null) return 0; */
116 BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 8),
117 /* r7 = sk_fullsock(skb); */
118 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
119 BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
120 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
121 /* r0 = sk_fullsock(skb); */
122 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
123 BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
124 /* if (r0 == null) return 0; */
125 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
126 /* if (r0 != r7) r0 = *(r7->type); */
127 BPF_JMP_REG(BPF_JEQ, BPF_REG_0, BPF_REG_7, 1), /* Use ! JEQ ! */
128 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_7, offsetof(struct bpf_sock, type)),
129 /* return 0; */
130 BPF_MOV64_IMM(BPF_REG_0, 0),
131 BPF_EXIT_INSN(),
132 },
133 .prog_type = BPF_PROG_TYPE_CGROUP_SKB,
134 .result = REJECT,
135 .errstr = "R7 invalid mem access 'sock_or_null'",
136 .result_unpriv = REJECT,
137 .errstr_unpriv = "R7 pointer comparison",
138},
139{
140 /* Maps are treated in a different branch of `mark_ptr_not_null_reg`,
141 * so separate test for maps case.
142 */
143 "jne/jeq infer not null, PTR_TO_MAP_VALUE_OR_NULL -> PTR_TO_MAP_VALUE",
144 .insns = {
145 /* r9 = &some stack to use as key */
146 BPF_ST_MEM(BPF_W, BPF_REG_10, -8, 0),
147 BPF_MOV64_REG(BPF_REG_9, BPF_REG_10),
148 BPF_ALU64_IMM(BPF_ADD, BPF_REG_9, -8),
149 /* r8 = process local map */
150 BPF_LD_MAP_FD(BPF_REG_8, 0),
151 /* r6 = map_lookup_elem(r8, r9); */
152 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
153 BPF_MOV64_REG(BPF_REG_2, BPF_REG_9),
154 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
155 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
156 /* r7 = map_lookup_elem(r8, r9); */
157 BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
158 BPF_MOV64_REG(BPF_REG_2, BPF_REG_9),
159 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
160 BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
161 /* if (r6 == 0) return 0; */
162 BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 2),
163 /* if (r6 != r7) return 0; */
164 BPF_JMP_REG(BPF_JNE, BPF_REG_6, BPF_REG_7, 1),
165 /* read *r7; */
166 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_7, offsetof(struct bpf_xdp_sock, queue_id)),
167 /* return 0; */
168 BPF_MOV64_IMM(BPF_REG_0, 0),
169 BPF_EXIT_INSN(),
170 },
171 .fixup_map_xskmap = { 3 },
172 .prog_type = BPF_PROG_TYPE_XDP,
173 .result = ACCEPT,
174},