Linux Audio

Check our new training course

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},