Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.13.7.
  1{
  2	"variable-offset ctx access",
  3	.insns = {
  4	/* Get an unknown value */
  5	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
  6	/* Make it small and 4-byte aligned */
  7	BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
  8	/* add it to skb.  We now have either &skb->len or
  9	 * &skb->pkt_type, but we don't know which
 10	 */
 11	BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
 12	/* dereference it */
 13	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
 14	BPF_EXIT_INSN(),
 15	},
 16	.errstr = "variable ctx access var_off=(0x0; 0x4)",
 17	.result = REJECT,
 18	.prog_type = BPF_PROG_TYPE_LWT_IN,
 19},
 20{
 21	"variable-offset stack access",
 22	.insns = {
 23	/* Fill the top 8 bytes of the stack */
 24	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 25	/* Get an unknown value */
 26	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
 27	/* Make it small and 4-byte aligned */
 28	BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
 29	BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8),
 30	/* add it to fp.  We now have either fp-4 or fp-8, but
 31	 * we don't know which
 32	 */
 33	BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
 34	/* dereference it */
 35	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
 36	BPF_EXIT_INSN(),
 37	},
 38	.errstr = "variable stack access var_off=(0xfffffffffffffff8; 0x4)",
 39	.result = REJECT,
 40	.prog_type = BPF_PROG_TYPE_LWT_IN,
 41},
 42{
 43	"indirect variable-offset stack access, unbounded",
 44	.insns = {
 45	BPF_MOV64_IMM(BPF_REG_2, 6),
 46	BPF_MOV64_IMM(BPF_REG_3, 28),
 47	/* Fill the top 16 bytes of the stack. */
 48	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
 49	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 50	/* Get an unknown value. */
 51	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_1, offsetof(struct bpf_sock_ops,
 52							   bytes_received)),
 53	/* Check the lower bound but don't check the upper one. */
 54	BPF_JMP_IMM(BPF_JSLT, BPF_REG_4, 0, 4),
 55	/* Point the lower bound to initialized stack. Offset is now in range
 56	 * from fp-16 to fp+0x7fffffffffffffef, i.e. max value is unbounded.
 57	 */
 58	BPF_ALU64_IMM(BPF_SUB, BPF_REG_4, 16),
 59	BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_10),
 60	BPF_MOV64_IMM(BPF_REG_5, 8),
 61	/* Dereference it indirectly. */
 62	BPF_EMIT_CALL(BPF_FUNC_getsockopt),
 63	BPF_MOV64_IMM(BPF_REG_0, 0),
 64	BPF_EXIT_INSN(),
 65	},
 66	.errstr = "R4 unbounded indirect variable offset stack access",
 67	.result = REJECT,
 68	.prog_type = BPF_PROG_TYPE_SOCK_OPS,
 69},
 70{
 71	"indirect variable-offset stack access, max out of bound",
 72	.insns = {
 73	/* Fill the top 8 bytes of the stack */
 74	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
 75	/* Get an unknown value */
 76	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
 77	/* Make it small and 4-byte aligned */
 78	BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
 79	BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 8),
 80	/* add it to fp.  We now have either fp-4 or fp-8, but
 81	 * we don't know which
 82	 */
 83	BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
 84	/* dereference it indirectly */
 85	BPF_LD_MAP_FD(BPF_REG_1, 0),
 86	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
 87	BPF_MOV64_IMM(BPF_REG_0, 0),
 88	BPF_EXIT_INSN(),
 89	},
 90	.fixup_map_hash_8b = { 5 },
 91	.errstr = "R2 max value is outside of stack bound",
 92	.result = REJECT,
 93	.prog_type = BPF_PROG_TYPE_LWT_IN,
 94},
 95{
 96	"indirect variable-offset stack access, min out of bound",
 97	.insns = {
 98	/* Fill the top 8 bytes of the stack */
 99	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
100	/* Get an unknown value */
101	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
102	/* Make it small and 4-byte aligned */
103	BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
104	BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 516),
105	/* add it to fp.  We now have either fp-516 or fp-512, but
106	 * we don't know which
107	 */
108	BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
109	/* dereference it indirectly */
110	BPF_LD_MAP_FD(BPF_REG_1, 0),
111	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
112	BPF_MOV64_IMM(BPF_REG_0, 0),
113	BPF_EXIT_INSN(),
114	},
115	.fixup_map_hash_8b = { 5 },
116	.errstr = "R2 min value is outside of stack bound",
117	.result = REJECT,
118	.prog_type = BPF_PROG_TYPE_LWT_IN,
119},
120{
121	"indirect variable-offset stack access, max_off+size > max_initialized",
122	.insns = {
123	/* Fill only the second from top 8 bytes of the stack. */
124	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
125	/* Get an unknown value. */
126	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
127	/* Make it small and 4-byte aligned. */
128	BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
129	BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 16),
130	/* Add it to fp.  We now have either fp-12 or fp-16, but we don't know
131	 * which. fp-12 size 8 is partially uninitialized stack.
132	 */
133	BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
134	/* Dereference it indirectly. */
135	BPF_LD_MAP_FD(BPF_REG_1, 0),
136	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
137	BPF_MOV64_IMM(BPF_REG_0, 0),
138	BPF_EXIT_INSN(),
139	},
140	.fixup_map_hash_8b = { 5 },
141	.errstr = "invalid indirect read from stack var_off",
142	.result = REJECT,
143	.prog_type = BPF_PROG_TYPE_LWT_IN,
144},
145{
146	"indirect variable-offset stack access, min_off < min_initialized",
147	.insns = {
148	/* Fill only the top 8 bytes of the stack. */
149	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
150	/* Get an unknown value */
151	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
152	/* Make it small and 4-byte aligned. */
153	BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
154	BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 16),
155	/* Add it to fp.  We now have either fp-12 or fp-16, but we don't know
156	 * which. fp-16 size 8 is partially uninitialized stack.
157	 */
158	BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
159	/* Dereference it indirectly. */
160	BPF_LD_MAP_FD(BPF_REG_1, 0),
161	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
162	BPF_MOV64_IMM(BPF_REG_0, 0),
163	BPF_EXIT_INSN(),
164	},
165	.fixup_map_hash_8b = { 5 },
166	.errstr = "invalid indirect read from stack var_off",
167	.result = REJECT,
168	.prog_type = BPF_PROG_TYPE_LWT_IN,
169},
170{
171	"indirect variable-offset stack access, priv vs unpriv",
172	.insns = {
173	/* Fill the top 16 bytes of the stack. */
174	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
175	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
176	/* Get an unknown value. */
177	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
178	/* Make it small and 4-byte aligned. */
179	BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
180	BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 16),
181	/* Add it to fp.  We now have either fp-12 or fp-16, we don't know
182	 * which, but either way it points to initialized stack.
183	 */
184	BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
185	/* Dereference it indirectly. */
186	BPF_LD_MAP_FD(BPF_REG_1, 0),
187	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
188	BPF_MOV64_IMM(BPF_REG_0, 0),
189	BPF_EXIT_INSN(),
190	},
191	.fixup_map_hash_8b = { 6 },
192	.errstr_unpriv = "R2 stack pointer arithmetic goes out of range, prohibited for !root",
193	.result_unpriv = REJECT,
194	.result = ACCEPT,
195	.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
196},
197{
198	"indirect variable-offset stack access, uninitialized",
199	.insns = {
200	BPF_MOV64_IMM(BPF_REG_2, 6),
201	BPF_MOV64_IMM(BPF_REG_3, 28),
202	/* Fill the top 16 bytes of the stack. */
203	BPF_ST_MEM(BPF_W, BPF_REG_10, -16, 0),
204	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
205	/* Get an unknown value. */
206	BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1, 0),
207	/* Make it small and 4-byte aligned. */
208	BPF_ALU64_IMM(BPF_AND, BPF_REG_4, 4),
209	BPF_ALU64_IMM(BPF_SUB, BPF_REG_4, 16),
210	/* Add it to fp.  We now have either fp-12 or fp-16, we don't know
211	 * which, but either way it points to initialized stack.
212	 */
213	BPF_ALU64_REG(BPF_ADD, BPF_REG_4, BPF_REG_10),
214	BPF_MOV64_IMM(BPF_REG_5, 8),
215	/* Dereference it indirectly. */
216	BPF_EMIT_CALL(BPF_FUNC_getsockopt),
217	BPF_MOV64_IMM(BPF_REG_0, 0),
218	BPF_EXIT_INSN(),
219	},
220	.errstr = "invalid indirect read from stack var_off",
221	.result = REJECT,
222	.prog_type = BPF_PROG_TYPE_SOCK_OPS,
223},
224{
225	"indirect variable-offset stack access, ok",
226	.insns = {
227	/* Fill the top 16 bytes of the stack. */
228	BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
229	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
230	/* Get an unknown value. */
231	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
232	/* Make it small and 4-byte aligned. */
233	BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 4),
234	BPF_ALU64_IMM(BPF_SUB, BPF_REG_2, 16),
235	/* Add it to fp.  We now have either fp-12 or fp-16, we don't know
236	 * which, but either way it points to initialized stack.
237	 */
238	BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_10),
239	/* Dereference it indirectly. */
240	BPF_LD_MAP_FD(BPF_REG_1, 0),
241	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
242	BPF_MOV64_IMM(BPF_REG_0, 0),
243	BPF_EXIT_INSN(),
244	},
245	.fixup_map_hash_8b = { 6 },
246	.result = ACCEPT,
247	.prog_type = BPF_PROG_TYPE_LWT_IN,
248},