1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */
3
4 #include <linux/bpf_verifier.h>
5 #include <linux/btf.h>
6 #include <linux/hashtable.h>
7 #include <linux/jhash.h>
8 #include <linux/slab.h>
9 #include <linux/sort.h>
10
11 #define verbose(env, fmt, args...) bpf_verifier_log_write(env, fmt, ##args)
12
13 struct per_frame_masks {
14 spis_t may_read; /* stack slots that may be read by this instruction */
15 spis_t must_write; /* stack slots written by this instruction */
16 spis_t live_before; /* stack slots that may be read by this insn and its successors */
17 };
18
19 /*
20 * A function instance keyed by (callsite, depth).
21 * Encapsulates read and write marks for each instruction in the function.
22 * Marks are tracked for each frame up to @depth.
23 */
24 struct func_instance {
25 struct hlist_node hl_node;
26 u32 callsite; /* call insn that invoked this subprog (subprog_start for depth 0) */
27 u32 depth; /* call depth (0 = entry subprog) */
28 u32 subprog; /* subprog index */
29 u32 subprog_start; /* cached env->subprog_info[subprog].start */
30 u32 insn_cnt; /* cached number of insns in the function */
31 /* Per frame, per instruction masks, frames allocated lazily. */
32 struct per_frame_masks *frames[MAX_CALL_FRAMES];
33 bool must_write_initialized;
34 };
35
36 struct live_stack_query {
37 struct func_instance *instances[MAX_CALL_FRAMES]; /* valid in range [0..curframe] */
38 u32 callsites[MAX_CALL_FRAMES]; /* callsite[i] = insn calling frame i+1 */
39 u32 curframe;
40 u32 insn_idx;
41 };
42
43 struct bpf_liveness {
44 DECLARE_HASHTABLE(func_instances, 8); /* maps (depth, callsite) to func_instance */
45 struct live_stack_query live_stack_query; /* cache to avoid repetitive ht lookups */
46 u32 subprog_calls; /* analyze_subprog() invocations */
47 };
48
49 /*
50 * Hash/compare key for func_instance: (depth, callsite).
51 * For depth == 0 (entry subprog), @callsite is the subprog start insn.
52 * For depth > 0, @callsite is the call instruction index that invoked the subprog.
53 */
instance_hash(u32 callsite,u32 depth)54 static u32 instance_hash(u32 callsite, u32 depth)
55 {
56 u32 key[2] = { depth, callsite };
57
58 return jhash2(key, 2, 0);
59 }
60
find_instance(struct bpf_verifier_env * env,u32 callsite,u32 depth)61 static struct func_instance *find_instance(struct bpf_verifier_env *env,
62 u32 callsite, u32 depth)
63 {
64 struct bpf_liveness *liveness = env->liveness;
65 struct func_instance *f;
66 u32 key = instance_hash(callsite, depth);
67
68 hash_for_each_possible(liveness->func_instances, f, hl_node, key)
69 if (f->depth == depth && f->callsite == callsite)
70 return f;
71 return NULL;
72 }
73
call_instance(struct bpf_verifier_env * env,struct func_instance * caller,u32 callsite,int subprog)74 static struct func_instance *call_instance(struct bpf_verifier_env *env,
75 struct func_instance *caller,
76 u32 callsite, int subprog)
77 {
78 u32 depth = caller ? caller->depth + 1 : 0;
79 u32 subprog_start = env->subprog_info[subprog].start;
80 u32 lookup_key = depth > 0 ? callsite : subprog_start;
81 struct func_instance *f;
82 u32 hash;
83
84 f = find_instance(env, lookup_key, depth);
85 if (f)
86 return f;
87
88 f = kvzalloc(sizeof(*f), GFP_KERNEL_ACCOUNT);
89 if (!f)
90 return ERR_PTR(-ENOMEM);
91 f->callsite = lookup_key;
92 f->depth = depth;
93 f->subprog = subprog;
94 f->subprog_start = subprog_start;
95 f->insn_cnt = (env->subprog_info + subprog + 1)->start - subprog_start;
96 hash = instance_hash(lookup_key, depth);
97 hash_add(env->liveness->func_instances, &f->hl_node, hash);
98 return f;
99 }
100
lookup_instance(struct bpf_verifier_env * env,struct bpf_verifier_state * st,u32 frameno)101 static struct func_instance *lookup_instance(struct bpf_verifier_env *env,
102 struct bpf_verifier_state *st,
103 u32 frameno)
104 {
105 u32 callsite, subprog_start;
106 struct func_instance *f;
107 u32 key, depth;
108
109 subprog_start = env->subprog_info[st->frame[frameno]->subprogno].start;
110 callsite = frameno > 0 ? st->frame[frameno]->callsite : subprog_start;
111
112 for (depth = frameno; ; depth--) {
113 key = depth > 0 ? callsite : subprog_start;
114 f = find_instance(env, key, depth);
115 if (f || depth == 0)
116 return f;
117 }
118 }
119
bpf_stack_liveness_init(struct bpf_verifier_env * env)120 int bpf_stack_liveness_init(struct bpf_verifier_env *env)
121 {
122 env->liveness = kvzalloc_obj(*env->liveness, GFP_KERNEL_ACCOUNT);
123 if (!env->liveness)
124 return -ENOMEM;
125 hash_init(env->liveness->func_instances);
126 return 0;
127 }
128
bpf_stack_liveness_free(struct bpf_verifier_env * env)129 void bpf_stack_liveness_free(struct bpf_verifier_env *env)
130 {
131 struct func_instance *instance;
132 struct hlist_node *tmp;
133 int bkt, i;
134
135 if (!env->liveness)
136 return;
137 hash_for_each_safe(env->liveness->func_instances, bkt, tmp, instance, hl_node) {
138 for (i = 0; i <= instance->depth; i++)
139 kvfree(instance->frames[i]);
140 kvfree(instance);
141 }
142 kvfree(env->liveness);
143 }
144
145 /*
146 * Convert absolute instruction index @insn_idx to an index relative
147 * to start of the function corresponding to @instance.
148 */
relative_idx(struct func_instance * instance,u32 insn_idx)149 static int relative_idx(struct func_instance *instance, u32 insn_idx)
150 {
151 return insn_idx - instance->subprog_start;
152 }
153
get_frame_masks(struct func_instance * instance,u32 frame,u32 insn_idx)154 static struct per_frame_masks *get_frame_masks(struct func_instance *instance,
155 u32 frame, u32 insn_idx)
156 {
157 if (!instance->frames[frame])
158 return NULL;
159
160 return &instance->frames[frame][relative_idx(instance, insn_idx)];
161 }
162
alloc_frame_masks(struct func_instance * instance,u32 frame,u32 insn_idx)163 static struct per_frame_masks *alloc_frame_masks(struct func_instance *instance,
164 u32 frame, u32 insn_idx)
165 {
166 struct per_frame_masks *arr;
167
168 if (!instance->frames[frame]) {
169 arr = kvzalloc_objs(*arr, instance->insn_cnt,
170 GFP_KERNEL_ACCOUNT);
171 instance->frames[frame] = arr;
172 if (!arr)
173 return ERR_PTR(-ENOMEM);
174 }
175 return get_frame_masks(instance, frame, insn_idx);
176 }
177
178 /* Accumulate may_read masks for @frame at @insn_idx */
mark_stack_read(struct func_instance * instance,u32 frame,u32 insn_idx,spis_t mask)179 static int mark_stack_read(struct func_instance *instance, u32 frame, u32 insn_idx, spis_t mask)
180 {
181 struct per_frame_masks *masks;
182
183 masks = alloc_frame_masks(instance, frame, insn_idx);
184 if (IS_ERR(masks))
185 return PTR_ERR(masks);
186 masks->may_read = spis_or(masks->may_read, mask);
187 return 0;
188 }
189
mark_stack_write(struct func_instance * instance,u32 frame,u32 insn_idx,spis_t mask)190 static int mark_stack_write(struct func_instance *instance, u32 frame, u32 insn_idx, spis_t mask)
191 {
192 struct per_frame_masks *masks;
193
194 masks = alloc_frame_masks(instance, frame, insn_idx);
195 if (IS_ERR(masks))
196 return PTR_ERR(masks);
197 masks->must_write = spis_or(masks->must_write, mask);
198 return 0;
199 }
200
bpf_jmp_offset(struct bpf_insn * insn)201 int bpf_jmp_offset(struct bpf_insn *insn)
202 {
203 u8 code = insn->code;
204
205 if (code == (BPF_JMP32 | BPF_JA))
206 return insn->imm;
207 return insn->off;
208 }
209
210 __diag_push();
211 __diag_ignore_all("-Woverride-init", "Allow field initialization overrides for opcode_info_tbl");
212
213 /*
214 * Returns an array of instructions succ, with succ->items[0], ...,
215 * succ->items[n-1] with successor instructions, where n=succ->cnt
216 */
217 inline struct bpf_iarray *
bpf_insn_successors(struct bpf_verifier_env * env,u32 idx)218 bpf_insn_successors(struct bpf_verifier_env *env, u32 idx)
219 {
220 static const struct opcode_info {
221 bool can_jump;
222 bool can_fallthrough;
223 } opcode_info_tbl[256] = {
224 [0 ... 255] = {.can_jump = false, .can_fallthrough = true},
225 #define _J(code, ...) \
226 [BPF_JMP | code] = __VA_ARGS__, \
227 [BPF_JMP32 | code] = __VA_ARGS__
228
229 _J(BPF_EXIT, {.can_jump = false, .can_fallthrough = false}),
230 _J(BPF_JA, {.can_jump = true, .can_fallthrough = false}),
231 _J(BPF_JEQ, {.can_jump = true, .can_fallthrough = true}),
232 _J(BPF_JNE, {.can_jump = true, .can_fallthrough = true}),
233 _J(BPF_JLT, {.can_jump = true, .can_fallthrough = true}),
234 _J(BPF_JLE, {.can_jump = true, .can_fallthrough = true}),
235 _J(BPF_JGT, {.can_jump = true, .can_fallthrough = true}),
236 _J(BPF_JGE, {.can_jump = true, .can_fallthrough = true}),
237 _J(BPF_JSGT, {.can_jump = true, .can_fallthrough = true}),
238 _J(BPF_JSGE, {.can_jump = true, .can_fallthrough = true}),
239 _J(BPF_JSLT, {.can_jump = true, .can_fallthrough = true}),
240 _J(BPF_JSLE, {.can_jump = true, .can_fallthrough = true}),
241 _J(BPF_JCOND, {.can_jump = true, .can_fallthrough = true}),
242 _J(BPF_JSET, {.can_jump = true, .can_fallthrough = true}),
243 #undef _J
244 };
245 struct bpf_prog *prog = env->prog;
246 struct bpf_insn *insn = &prog->insnsi[idx];
247 const struct opcode_info *opcode_info;
248 struct bpf_iarray *succ, *jt;
249 int insn_sz;
250
251 jt = env->insn_aux_data[idx].jt;
252 if (unlikely(jt))
253 return jt;
254
255 /* pre-allocated array of size up to 2; reset cnt, as it may have been used already */
256 succ = env->succ;
257 succ->cnt = 0;
258
259 opcode_info = &opcode_info_tbl[BPF_CLASS(insn->code) | BPF_OP(insn->code)];
260 insn_sz = bpf_is_ldimm64(insn) ? 2 : 1;
261 if (opcode_info->can_fallthrough)
262 succ->items[succ->cnt++] = idx + insn_sz;
263
264 if (opcode_info->can_jump)
265 succ->items[succ->cnt++] = idx + bpf_jmp_offset(insn) + 1;
266
267 return succ;
268 }
269
270 __diag_pop();
271
272
update_insn(struct bpf_verifier_env * env,struct func_instance * instance,u32 frame,u32 insn_idx)273 static inline bool update_insn(struct bpf_verifier_env *env,
274 struct func_instance *instance, u32 frame, u32 insn_idx)
275 {
276 spis_t new_before, new_after;
277 struct per_frame_masks *insn, *succ_insn;
278 struct bpf_iarray *succ;
279 u32 s;
280 bool changed;
281
282 succ = bpf_insn_successors(env, insn_idx);
283 if (succ->cnt == 0)
284 return false;
285
286 changed = false;
287 insn = get_frame_masks(instance, frame, insn_idx);
288 new_before = SPIS_ZERO;
289 new_after = SPIS_ZERO;
290 for (s = 0; s < succ->cnt; ++s) {
291 succ_insn = get_frame_masks(instance, frame, succ->items[s]);
292 new_after = spis_or(new_after, succ_insn->live_before);
293 }
294 /*
295 * New "live_before" is a union of all "live_before" of successors
296 * minus slots written by instruction plus slots read by instruction.
297 * new_before = (new_after & ~insn->must_write) | insn->may_read
298 */
299 new_before = spis_or(spis_and(new_after, spis_not(insn->must_write)),
300 insn->may_read);
301 changed |= !spis_equal(new_before, insn->live_before);
302 insn->live_before = new_before;
303 return changed;
304 }
305
306 /* Fixed-point computation of @live_before marks */
update_instance(struct bpf_verifier_env * env,struct func_instance * instance)307 static void update_instance(struct bpf_verifier_env *env, struct func_instance *instance)
308 {
309 u32 i, frame, po_start, po_end;
310 int *insn_postorder = env->cfg.insn_postorder;
311 struct bpf_subprog_info *subprog;
312 bool changed;
313
314 instance->must_write_initialized = true;
315 subprog = &env->subprog_info[instance->subprog];
316 po_start = subprog->postorder_start;
317 po_end = (subprog + 1)->postorder_start;
318 /* repeat until fixed point is reached */
319 do {
320 changed = false;
321 for (frame = 0; frame <= instance->depth; frame++) {
322 if (!instance->frames[frame])
323 continue;
324
325 for (i = po_start; i < po_end; i++)
326 changed |= update_insn(env, instance, frame, insn_postorder[i]);
327 }
328 } while (changed);
329 }
330
is_live_before(struct func_instance * instance,u32 insn_idx,u32 frameno,u32 half_spi)331 static bool is_live_before(struct func_instance *instance, u32 insn_idx, u32 frameno, u32 half_spi)
332 {
333 struct per_frame_masks *masks;
334
335 masks = get_frame_masks(instance, frameno, insn_idx);
336 return masks && spis_test_bit(masks->live_before, half_spi);
337 }
338
bpf_live_stack_query_init(struct bpf_verifier_env * env,struct bpf_verifier_state * st)339 int bpf_live_stack_query_init(struct bpf_verifier_env *env, struct bpf_verifier_state *st)
340 {
341 struct live_stack_query *q = &env->liveness->live_stack_query;
342 struct func_instance *instance;
343 u32 frame;
344
345 memset(q, 0, sizeof(*q));
346 for (frame = 0; frame <= st->curframe; frame++) {
347 instance = lookup_instance(env, st, frame);
348 if (IS_ERR_OR_NULL(instance))
349 q->instances[frame] = NULL;
350 else
351 q->instances[frame] = instance;
352 if (frame < st->curframe)
353 q->callsites[frame] = st->frame[frame + 1]->callsite;
354 }
355 q->curframe = st->curframe;
356 q->insn_idx = st->insn_idx;
357 return 0;
358 }
359
bpf_stack_slot_alive(struct bpf_verifier_env * env,u32 frameno,u32 half_spi)360 bool bpf_stack_slot_alive(struct bpf_verifier_env *env, u32 frameno, u32 half_spi)
361 {
362 /*
363 * Slot is alive if it is read before q->insn_idx in current func instance,
364 * or if for some outer func instance:
365 * - alive before callsite if callsite calls callback, otherwise
366 * - alive after callsite
367 */
368 struct live_stack_query *q = &env->liveness->live_stack_query;
369 struct func_instance *instance, *curframe_instance;
370 u32 i, callsite, rel;
371 int cur_delta, delta;
372 bool alive = false;
373
374 curframe_instance = q->instances[q->curframe];
375 if (!curframe_instance)
376 return true;
377 cur_delta = (int)curframe_instance->depth - (int)q->curframe;
378 rel = frameno + cur_delta;
379 if (rel <= curframe_instance->depth)
380 alive = is_live_before(curframe_instance, q->insn_idx, rel, half_spi);
381
382 if (alive)
383 return true;
384
385 for (i = frameno; i < q->curframe; i++) {
386 instance = q->instances[i];
387 if (!instance)
388 return true;
389 /* Map actual frameno to frame index within this instance */
390 delta = (int)instance->depth - (int)i;
391 rel = frameno + delta;
392 if (rel > instance->depth)
393 return true;
394
395 /* Get callsite from verifier state, not from instance callchain */
396 callsite = q->callsites[i];
397
398 alive = bpf_calls_callback(env, callsite)
399 ? is_live_before(instance, callsite, rel, half_spi)
400 : is_live_before(instance, callsite + 1, rel, half_spi);
401 if (alive)
402 return true;
403 }
404
405 return false;
406 }
407
fmt_subprog(struct bpf_verifier_env * env,int subprog)408 static char *fmt_subprog(struct bpf_verifier_env *env, int subprog)
409 {
410 const char *name = env->subprog_info[subprog].name;
411
412 snprintf(env->tmp_str_buf, sizeof(env->tmp_str_buf),
413 "subprog#%d%s%s", subprog, name ? " " : "", name ? name : "");
414 return env->tmp_str_buf;
415 }
416
fmt_instance(struct bpf_verifier_env * env,struct func_instance * instance)417 static char *fmt_instance(struct bpf_verifier_env *env, struct func_instance *instance)
418 {
419 snprintf(env->tmp_str_buf, sizeof(env->tmp_str_buf),
420 "(d%d,cs%d)", instance->depth, instance->callsite);
421 return env->tmp_str_buf;
422 }
423
spi_off(int spi)424 static int spi_off(int spi)
425 {
426 return -(spi + 1) * BPF_REG_SIZE;
427 }
428
429 /*
430 * When both halves of an 8-byte SPI are set, print as "-8","-16",...
431 * When only one half is set, print as "-4h","-8h",...
432 * Runs of 3+ consecutive fully-set SPIs are collapsed: "fp0-8..-24"
433 */
fmt_spis_mask(struct bpf_verifier_env * env,int frame,bool first,spis_t spis)434 static char *fmt_spis_mask(struct bpf_verifier_env *env, int frame, bool first, spis_t spis)
435 {
436 int buf_sz = sizeof(env->tmp_str_buf);
437 char *buf = env->tmp_str_buf;
438 int spi, n, run_start;
439
440 buf[0] = '\0';
441
442 for (spi = 0; spi < STACK_SLOTS / 2 && buf_sz > 0; spi++) {
443 bool lo = spis_test_bit(spis, spi * 2);
444 bool hi = spis_test_bit(spis, spi * 2 + 1);
445 const char *space = first ? "" : " ";
446
447 if (!lo && !hi)
448 continue;
449
450 if (!lo || !hi) {
451 /* half-spi */
452 n = scnprintf(buf, buf_sz, "%sfp%d%d%s",
453 space, frame, spi_off(spi) + (lo ? STACK_SLOT_SZ : 0), "h");
454 } else if (spi + 2 < STACK_SLOTS / 2 &&
455 spis_test_bit(spis, spi * 2 + 2) &&
456 spis_test_bit(spis, spi * 2 + 3) &&
457 spis_test_bit(spis, spi * 2 + 4) &&
458 spis_test_bit(spis, spi * 2 + 5)) {
459 /* 3+ consecutive full spis */
460 run_start = spi;
461 while (spi + 1 < STACK_SLOTS / 2 &&
462 spis_test_bit(spis, (spi + 1) * 2) &&
463 spis_test_bit(spis, (spi + 1) * 2 + 1))
464 spi++;
465 n = scnprintf(buf, buf_sz, "%sfp%d%d..%d",
466 space, frame, spi_off(run_start), spi_off(spi));
467 } else {
468 /* just a full spi */
469 n = scnprintf(buf, buf_sz, "%sfp%d%d", space, frame, spi_off(spi));
470 }
471 first = false;
472 buf += n;
473 buf_sz -= n;
474 }
475 return env->tmp_str_buf;
476 }
477
print_instance(struct bpf_verifier_env * env,struct func_instance * instance)478 static void print_instance(struct bpf_verifier_env *env, struct func_instance *instance)
479 {
480 int start = env->subprog_info[instance->subprog].start;
481 struct bpf_insn *insns = env->prog->insnsi;
482 struct per_frame_masks *masks;
483 int len = instance->insn_cnt;
484 int insn_idx, frame, i;
485 bool has_use, has_def;
486 u64 pos, insn_pos;
487
488 if (!(env->log.level & BPF_LOG_LEVEL2))
489 return;
490
491 verbose(env, "stack use/def %s ", fmt_subprog(env, instance->subprog));
492 verbose(env, "%s:\n", fmt_instance(env, instance));
493 for (i = 0; i < len; i++) {
494 insn_idx = start + i;
495 has_use = false;
496 has_def = false;
497 pos = env->log.end_pos;
498 verbose(env, "%3d: ", insn_idx);
499 bpf_verbose_insn(env, &insns[insn_idx]);
500 bpf_vlog_reset(&env->log, env->log.end_pos - 1); /* remove \n */
501 insn_pos = env->log.end_pos;
502 verbose(env, "%*c;", bpf_vlog_alignment(insn_pos - pos), ' ');
503 pos = env->log.end_pos;
504 verbose(env, " use: ");
505 for (frame = instance->depth; frame >= 0; --frame) {
506 masks = get_frame_masks(instance, frame, insn_idx);
507 if (!masks || spis_is_zero(masks->may_read))
508 continue;
509 verbose(env, "%s", fmt_spis_mask(env, frame, !has_use, masks->may_read));
510 has_use = true;
511 }
512 if (!has_use)
513 bpf_vlog_reset(&env->log, pos);
514 pos = env->log.end_pos;
515 verbose(env, " def: ");
516 for (frame = instance->depth; frame >= 0; --frame) {
517 masks = get_frame_masks(instance, frame, insn_idx);
518 if (!masks || spis_is_zero(masks->must_write))
519 continue;
520 verbose(env, "%s", fmt_spis_mask(env, frame, !has_def, masks->must_write));
521 has_def = true;
522 }
523 if (!has_def)
524 bpf_vlog_reset(&env->log, has_use ? pos : insn_pos);
525 verbose(env, "\n");
526 if (bpf_is_ldimm64(&insns[insn_idx]))
527 i++;
528 }
529 }
530
cmp_instances(const void * pa,const void * pb)531 static int cmp_instances(const void *pa, const void *pb)
532 {
533 struct func_instance *a = *(struct func_instance **)pa;
534 struct func_instance *b = *(struct func_instance **)pb;
535 int dcallsite = (int)a->callsite - b->callsite;
536 int ddepth = (int)a->depth - b->depth;
537
538 if (dcallsite)
539 return dcallsite;
540 if (ddepth)
541 return ddepth;
542 return 0;
543 }
544
545 /* print use/def slots for all instances ordered by callsite first, then by depth */
print_instances(struct bpf_verifier_env * env)546 static int print_instances(struct bpf_verifier_env *env)
547 {
548 struct func_instance *instance, **sorted_instances;
549 struct bpf_liveness *liveness = env->liveness;
550 int i, bkt, cnt;
551
552 cnt = 0;
553 hash_for_each(liveness->func_instances, bkt, instance, hl_node)
554 cnt++;
555 sorted_instances = kvmalloc_objs(*sorted_instances, cnt, GFP_KERNEL_ACCOUNT);
556 if (!sorted_instances)
557 return -ENOMEM;
558 cnt = 0;
559 hash_for_each(liveness->func_instances, bkt, instance, hl_node)
560 sorted_instances[cnt++] = instance;
561 sort(sorted_instances, cnt, sizeof(*sorted_instances), cmp_instances, NULL);
562 for (i = 0; i < cnt; i++)
563 print_instance(env, sorted_instances[i]);
564 kvfree(sorted_instances);
565 return 0;
566 }
567
568 /*
569 * Per-register tracking state for compute_subprog_args().
570 * Tracks which frame's FP a value is derived from
571 * and the byte offset from that frame's FP.
572 *
573 * The .frame field forms a lattice with three levels of precision:
574 *
575 * precise {frame=N, off=V} -- known absolute frame index and byte offset
576 * |
577 * offset-imprecise {frame=N, cnt=0}
578 * | -- known frame identity, unknown offset
579 * fully-imprecise {frame=ARG_IMPRECISE, mask=bitmask}
580 * -- unknown frame identity; .mask is a
581 * bitmask of which frame indices might be
582 * involved
583 *
584 * At CFG merge points, arg_track_join() moves down the lattice:
585 * - same frame + same offset -> precise
586 * - same frame + different offset -> offset-imprecise
587 * - different frames -> fully-imprecise (bitmask OR)
588 *
589 * At memory access sites (LDX/STX/ST), offset-imprecise marks only
590 * the known frame's access mask as SPIS_ALL, while fully-imprecise
591 * iterates bits in the bitmask and routes each frame to its target.
592 */
593 #define MAX_ARG_OFFSETS 4
594
595 struct arg_track {
596 union {
597 s16 off[MAX_ARG_OFFSETS]; /* byte offsets; off_cnt says how many */
598 u16 mask; /* arg bitmask when arg == ARG_IMPRECISE */
599 };
600 s8 frame; /* absolute frame index, or enum arg_track_state */
601 s8 off_cnt; /* 0 = offset-imprecise, 1-4 = # of precise offsets */
602 };
603
604 enum arg_track_state {
605 ARG_NONE = -1, /* not derived from any argument */
606 ARG_UNVISITED = -2, /* not yet reached by dataflow */
607 ARG_IMPRECISE = -3, /* lost identity; .mask is arg bitmask */
608 };
609
610 /* Track callee stack slots fp-8 through fp-512 (64 slots of 8 bytes each) */
611 #define MAX_ARG_SPILL_SLOTS 64
612
arg_is_visited(const struct arg_track * at)613 static bool arg_is_visited(const struct arg_track *at)
614 {
615 return at->frame != ARG_UNVISITED;
616 }
617
arg_is_fp(const struct arg_track * at)618 static bool arg_is_fp(const struct arg_track *at)
619 {
620 return at->frame >= 0 || at->frame == ARG_IMPRECISE;
621 }
622
verbose_arg_track(struct bpf_verifier_env * env,struct arg_track * at)623 static void verbose_arg_track(struct bpf_verifier_env *env, struct arg_track *at)
624 {
625 int i;
626
627 switch (at->frame) {
628 case ARG_NONE: verbose(env, "_"); break;
629 case ARG_UNVISITED: verbose(env, "?"); break;
630 case ARG_IMPRECISE: verbose(env, "IMP%x", at->mask); break;
631 default:
632 /* frame >= 0: absolute frame index */
633 if (at->off_cnt == 0) {
634 verbose(env, "fp%d ?", at->frame);
635 } else {
636 for (i = 0; i < at->off_cnt; i++) {
637 if (i)
638 verbose(env, "|");
639 verbose(env, "fp%d%+d", at->frame, at->off[i]);
640 }
641 }
642 break;
643 }
644 }
645
arg_track_eq(const struct arg_track * a,const struct arg_track * b)646 static bool arg_track_eq(const struct arg_track *a, const struct arg_track *b)
647 {
648 int i;
649
650 if (a->frame != b->frame)
651 return false;
652 if (a->frame == ARG_IMPRECISE)
653 return a->mask == b->mask;
654 if (a->frame < 0)
655 return true;
656 if (a->off_cnt != b->off_cnt)
657 return false;
658 for (i = 0; i < a->off_cnt; i++)
659 if (a->off[i] != b->off[i])
660 return false;
661 return true;
662 }
663
arg_single(s8 arg,s16 off)664 static struct arg_track arg_single(s8 arg, s16 off)
665 {
666 struct arg_track at = {};
667
668 at.frame = arg;
669 at.off[0] = off;
670 at.off_cnt = 1;
671 return at;
672 }
673
674 /*
675 * Merge two sorted offset arrays, deduplicate.
676 * Returns off_cnt=0 if the result exceeds MAX_ARG_OFFSETS.
677 * Both args must have the same frame and off_cnt > 0.
678 */
arg_merge_offsets(struct arg_track a,struct arg_track b)679 static struct arg_track arg_merge_offsets(struct arg_track a, struct arg_track b)
680 {
681 struct arg_track result = { .frame = a.frame };
682 struct arg_track imp = { .frame = a.frame };
683 int i = 0, j = 0, k = 0;
684
685 while (i < a.off_cnt && j < b.off_cnt) {
686 s16 v;
687
688 if (a.off[i] <= b.off[j]) {
689 v = a.off[i++];
690 if (v == b.off[j])
691 j++;
692 } else {
693 v = b.off[j++];
694 }
695 if (k > 0 && result.off[k - 1] == v)
696 continue;
697 if (k >= MAX_ARG_OFFSETS)
698 return imp;
699 result.off[k++] = v;
700 }
701 while (i < a.off_cnt) {
702 if (k >= MAX_ARG_OFFSETS)
703 return imp;
704 result.off[k++] = a.off[i++];
705 }
706 while (j < b.off_cnt) {
707 if (k >= MAX_ARG_OFFSETS)
708 return imp;
709 result.off[k++] = b.off[j++];
710 }
711 result.off_cnt = k;
712 return result;
713 }
714
715 /*
716 * Merge two arg_tracks into ARG_IMPRECISE, collecting the frame
717 * bits from both operands. Precise frame indices (frame >= 0)
718 * contribute a single bit; existing ARG_IMPRECISE values
719 * contribute their full bitmask.
720 */
arg_join_imprecise(struct arg_track a,struct arg_track b)721 static struct arg_track arg_join_imprecise(struct arg_track a, struct arg_track b)
722 {
723 u32 m = 0;
724
725 if (a.frame >= 0)
726 m |= BIT(a.frame);
727 else if (a.frame == ARG_IMPRECISE)
728 m |= a.mask;
729
730 if (b.frame >= 0)
731 m |= BIT(b.frame);
732 else if (b.frame == ARG_IMPRECISE)
733 m |= b.mask;
734
735 return (struct arg_track){ .mask = m, .frame = ARG_IMPRECISE };
736 }
737
738 /* Join two arg_track values at merge points */
__arg_track_join(struct arg_track a,struct arg_track b)739 static struct arg_track __arg_track_join(struct arg_track a, struct arg_track b)
740 {
741 if (!arg_is_visited(&b))
742 return a;
743 if (!arg_is_visited(&a))
744 return b;
745 if (a.frame == b.frame && a.frame >= 0) {
746 /* Both offset-imprecise: stay imprecise */
747 if (a.off_cnt == 0 || b.off_cnt == 0)
748 return (struct arg_track){ .frame = a.frame };
749 /* Merge offset sets; falls back to off_cnt=0 if >4 */
750 return arg_merge_offsets(a, b);
751 }
752
753 /*
754 * args are different, but one of them is known
755 * arg + none -> arg
756 * none + arg -> arg
757 *
758 * none + none -> none
759 */
760 if (a.frame == ARG_NONE && b.frame == ARG_NONE)
761 return a;
762 if (a.frame >= 0 && b.frame == ARG_NONE) {
763 /*
764 * When joining single fp-N add fake fp+0 to
765 * keep stack_use and prevent stack_def
766 */
767 if (a.off_cnt == 1)
768 return arg_merge_offsets(a, arg_single(a.frame, 0));
769 return a;
770 }
771 if (b.frame >= 0 && a.frame == ARG_NONE) {
772 if (b.off_cnt == 1)
773 return arg_merge_offsets(b, arg_single(b.frame, 0));
774 return b;
775 }
776
777 return arg_join_imprecise(a, b);
778 }
779
arg_track_join(struct bpf_verifier_env * env,int idx,int target,int r,struct arg_track * in,struct arg_track out)780 static bool arg_track_join(struct bpf_verifier_env *env, int idx, int target, int r,
781 struct arg_track *in, struct arg_track out)
782 {
783 struct arg_track old = *in;
784 struct arg_track new_val = __arg_track_join(old, out);
785
786 if (arg_track_eq(&new_val, &old))
787 return false;
788
789 *in = new_val;
790 if (!(env->log.level & BPF_LOG_LEVEL2) || !arg_is_visited(&old))
791 return true;
792
793 verbose(env, "arg JOIN insn %d -> %d ", idx, target);
794 if (r >= 0)
795 verbose(env, "r%d: ", r);
796 else
797 verbose(env, "fp%+d: ", r * 8);
798 verbose_arg_track(env, &old);
799 verbose(env, " + ");
800 verbose_arg_track(env, &out);
801 verbose(env, " => ");
802 verbose_arg_track(env, &new_val);
803 verbose(env, "\n");
804 return true;
805 }
806
807 /*
808 * Compute the result when an ALU op destroys offset precision.
809 * If a single arg is identifiable, preserve it with OFF_IMPRECISE.
810 * If two different args are involved or one is already ARG_IMPRECISE,
811 * the result is fully ARG_IMPRECISE.
812 */
arg_track_alu64(struct arg_track * dst,const struct arg_track * src)813 static void arg_track_alu64(struct arg_track *dst, const struct arg_track *src)
814 {
815 WARN_ON_ONCE(!arg_is_visited(dst));
816 WARN_ON_ONCE(!arg_is_visited(src));
817
818 if (dst->frame >= 0 && (src->frame == ARG_NONE || src->frame == dst->frame)) {
819 /*
820 * rX += rY where rY is not arg derived
821 * rX += rX
822 */
823 dst->off_cnt = 0;
824 return;
825 }
826 if (src->frame >= 0 && dst->frame == ARG_NONE) {
827 /*
828 * rX += rY where rX is not arg derived
829 * rY identity leaks into rX
830 */
831 dst->off_cnt = 0;
832 dst->frame = src->frame;
833 return;
834 }
835
836 if (dst->frame == ARG_NONE && src->frame == ARG_NONE)
837 return;
838
839 *dst = arg_join_imprecise(*dst, *src);
840 }
841
arg_add(s16 off,s64 delta,s16 * out)842 static bool arg_add(s16 off, s64 delta, s16 *out)
843 {
844 s16 d = delta;
845
846 if (d != delta)
847 return true;
848 return check_add_overflow(off, d, out);
849 }
850
arg_padd(struct arg_track * at,s64 delta)851 static void arg_padd(struct arg_track *at, s64 delta)
852 {
853 int i;
854
855 if (at->off_cnt == 0)
856 return;
857 for (i = 0; i < at->off_cnt; i++) {
858 s16 new_off;
859
860 if (arg_add(at->off[i], delta, &new_off)) {
861 at->off_cnt = 0;
862 return;
863 }
864 at->off[i] = new_off;
865 }
866 }
867
868 /*
869 * Convert a byte offset from FP to a callee stack slot index.
870 * Returns -1 if out of range or not 8-byte aligned.
871 * Slot 0 = fp-8, slot 1 = fp-16, ..., slot 7 = fp-64, ....
872 */
fp_off_to_slot(s16 off)873 static int fp_off_to_slot(s16 off)
874 {
875 if (off >= 0 || off < -(int)(MAX_ARG_SPILL_SLOTS * 8))
876 return -1;
877 if (off % 8)
878 return -1;
879 return (-off) / 8 - 1;
880 }
881
fill_from_stack(struct bpf_insn * insn,struct arg_track * at_out,int reg,struct arg_track * at_stack_out,int depth)882 static struct arg_track fill_from_stack(struct bpf_insn *insn,
883 struct arg_track *at_out, int reg,
884 struct arg_track *at_stack_out,
885 int depth)
886 {
887 struct arg_track imp = {
888 .mask = (1u << (depth + 1)) - 1,
889 .frame = ARG_IMPRECISE
890 };
891 struct arg_track result = { .frame = ARG_NONE };
892 int cnt, i;
893
894 if (reg == BPF_REG_FP) {
895 int slot = fp_off_to_slot(insn->off);
896
897 return slot >= 0 ? at_stack_out[slot] : imp;
898 }
899 cnt = at_out[reg].off_cnt;
900 if (cnt == 0)
901 return imp;
902
903 for (i = 0; i < cnt; i++) {
904 s16 fp_off, slot;
905
906 if (arg_add(at_out[reg].off[i], insn->off, &fp_off))
907 return imp;
908 slot = fp_off_to_slot(fp_off);
909 if (slot < 0)
910 return imp;
911 result = __arg_track_join(result, at_stack_out[slot]);
912 }
913 return result;
914 }
915
916 /*
917 * Spill @val to all possible stack slots indicated by the FP offsets in @reg.
918 * For an 8-byte store, single candidate slot gets @val. multi-slots are joined.
919 * sub-8-byte store joins with ARG_NONE.
920 * When exact offset is unknown conservatively add reg values to all slots in at_stack_out.
921 */
spill_to_stack(struct bpf_insn * insn,struct arg_track * at_out,int reg,struct arg_track * at_stack_out,struct arg_track * val,u32 sz)922 static void spill_to_stack(struct bpf_insn *insn, struct arg_track *at_out,
923 int reg, struct arg_track *at_stack_out,
924 struct arg_track *val, u32 sz)
925 {
926 struct arg_track none = { .frame = ARG_NONE };
927 struct arg_track new_val = sz == 8 ? *val : none;
928 int cnt, i;
929
930 if (reg == BPF_REG_FP) {
931 int slot = fp_off_to_slot(insn->off);
932
933 if (slot >= 0)
934 at_stack_out[slot] = new_val;
935 return;
936 }
937 cnt = at_out[reg].off_cnt;
938 if (cnt == 0) {
939 for (int slot = 0; slot < MAX_ARG_SPILL_SLOTS; slot++)
940 at_stack_out[slot] = __arg_track_join(at_stack_out[slot], new_val);
941 return;
942 }
943 for (i = 0; i < cnt; i++) {
944 s16 fp_off;
945 int slot;
946
947 if (arg_add(at_out[reg].off[i], insn->off, &fp_off))
948 continue;
949 slot = fp_off_to_slot(fp_off);
950 if (slot < 0)
951 continue;
952 if (cnt == 1)
953 at_stack_out[slot] = new_val;
954 else
955 at_stack_out[slot] = __arg_track_join(at_stack_out[slot], new_val);
956 }
957 }
958
959 /*
960 * Clear all tracked callee stack slots overlapping the byte range
961 * [off, off+sz-1] where off is a negative FP-relative offset.
962 */
clear_overlapping_stack_slots(struct arg_track * at_stack,s16 off,u32 sz,int cnt)963 static void clear_overlapping_stack_slots(struct arg_track *at_stack, s16 off, u32 sz, int cnt)
964 {
965 struct arg_track none = { .frame = ARG_NONE };
966
967 if (cnt == 0) {
968 for (int i = 0; i < MAX_ARG_SPILL_SLOTS; i++)
969 at_stack[i] = __arg_track_join(at_stack[i], none);
970 return;
971 }
972 for (int i = 0; i < MAX_ARG_SPILL_SLOTS; i++) {
973 int slot_start = -((i + 1) * 8);
974 int slot_end = slot_start + 8;
975
976 if (slot_start < off + (int)sz && slot_end > off) {
977 if (cnt == 1)
978 at_stack[i] = none;
979 else
980 at_stack[i] = __arg_track_join(at_stack[i], none);
981 }
982 }
983 }
984
985 /*
986 * Clear stack slots overlapping all possible FP offsets in @reg.
987 */
clear_stack_for_all_offs(struct bpf_insn * insn,struct arg_track * at_out,int reg,struct arg_track * at_stack_out,u32 sz)988 static void clear_stack_for_all_offs(struct bpf_insn *insn,
989 struct arg_track *at_out, int reg,
990 struct arg_track *at_stack_out, u32 sz)
991 {
992 int cnt, i;
993
994 if (reg == BPF_REG_FP) {
995 clear_overlapping_stack_slots(at_stack_out, insn->off, sz, 1);
996 return;
997 }
998 cnt = at_out[reg].off_cnt;
999 if (cnt == 0) {
1000 clear_overlapping_stack_slots(at_stack_out, 0, sz, cnt);
1001 return;
1002 }
1003 for (i = 0; i < cnt; i++) {
1004 s16 fp_off;
1005
1006 if (arg_add(at_out[reg].off[i], insn->off, &fp_off)) {
1007 clear_overlapping_stack_slots(at_stack_out, 0, sz, 0);
1008 break;
1009 }
1010 clear_overlapping_stack_slots(at_stack_out, fp_off, sz, cnt);
1011 }
1012 }
1013
arg_track_log(struct bpf_verifier_env * env,struct bpf_insn * insn,int idx,struct arg_track * at_in,struct arg_track * at_stack_in,struct arg_track * at_out,struct arg_track * at_stack_out)1014 static void arg_track_log(struct bpf_verifier_env *env, struct bpf_insn *insn, int idx,
1015 struct arg_track *at_in, struct arg_track *at_stack_in,
1016 struct arg_track *at_out, struct arg_track *at_stack_out)
1017 {
1018 bool printed = false;
1019 int i;
1020
1021 if (!(env->log.level & BPF_LOG_LEVEL2))
1022 return;
1023 for (i = 0; i < MAX_BPF_REG; i++) {
1024 if (arg_track_eq(&at_out[i], &at_in[i]))
1025 continue;
1026 if (!printed) {
1027 verbose(env, "%3d: ", idx);
1028 bpf_verbose_insn(env, insn);
1029 bpf_vlog_reset(&env->log, env->log.end_pos - 1);
1030 printed = true;
1031 }
1032 verbose(env, "\tr%d: ", i); verbose_arg_track(env, &at_in[i]);
1033 verbose(env, " -> "); verbose_arg_track(env, &at_out[i]);
1034 }
1035 for (i = 0; i < MAX_ARG_SPILL_SLOTS; i++) {
1036 if (arg_track_eq(&at_stack_out[i], &at_stack_in[i]))
1037 continue;
1038 if (!printed) {
1039 verbose(env, "%3d: ", idx);
1040 bpf_verbose_insn(env, insn);
1041 bpf_vlog_reset(&env->log, env->log.end_pos - 1);
1042 printed = true;
1043 }
1044 verbose(env, "\tfp%+d: ", -(i + 1) * 8); verbose_arg_track(env, &at_stack_in[i]);
1045 verbose(env, " -> "); verbose_arg_track(env, &at_stack_out[i]);
1046 }
1047 if (printed)
1048 verbose(env, "\n");
1049 }
1050
can_be_local_fp(int depth,int regno,struct arg_track * at)1051 static bool can_be_local_fp(int depth, int regno, struct arg_track *at)
1052 {
1053 return regno == BPF_REG_FP || at->frame == depth ||
1054 (at->frame == ARG_IMPRECISE && (at->mask & BIT(depth)));
1055 }
1056
1057 /*
1058 * Pure dataflow transfer function for arg_track state.
1059 * Updates at_out[] based on how the instruction modifies registers.
1060 * Tracks spill/fill, but not other memory accesses.
1061 */
arg_track_xfer(struct bpf_verifier_env * env,struct bpf_insn * insn,int insn_idx,struct arg_track * at_out,struct arg_track * at_stack_out,struct func_instance * instance,u32 * callsites)1062 static void arg_track_xfer(struct bpf_verifier_env *env, struct bpf_insn *insn,
1063 int insn_idx,
1064 struct arg_track *at_out, struct arg_track *at_stack_out,
1065 struct func_instance *instance,
1066 u32 *callsites)
1067 {
1068 int depth = instance->depth;
1069 u8 class = BPF_CLASS(insn->code);
1070 u8 code = BPF_OP(insn->code);
1071 struct arg_track *dst = &at_out[insn->dst_reg];
1072 struct arg_track *src = &at_out[insn->src_reg];
1073 struct arg_track none = { .frame = ARG_NONE };
1074 int r;
1075
1076 if (class == BPF_ALU64 && BPF_SRC(insn->code) == BPF_K) {
1077 if (code == BPF_MOV) {
1078 *dst = none;
1079 } else if (dst->frame >= 0) {
1080 if (code == BPF_ADD)
1081 arg_padd(dst, insn->imm);
1082 else if (code == BPF_SUB)
1083 arg_padd(dst, -(s64)insn->imm);
1084 else
1085 /* Any other 64-bit alu on the pointer makes it imprecise */
1086 dst->off_cnt = 0;
1087 } /* else if dst->frame is imprecise it stays so */
1088 } else if (class == BPF_ALU64 && BPF_SRC(insn->code) == BPF_X) {
1089 if (code == BPF_MOV) {
1090 if (insn->off == 0) {
1091 *dst = *src;
1092 } else {
1093 /* addr_space_cast destroys a pointer */
1094 *dst = none;
1095 }
1096 } else {
1097 arg_track_alu64(dst, src);
1098 }
1099 } else if (class == BPF_ALU) {
1100 /*
1101 * 32-bit alu destroys the pointer.
1102 * If src was a pointer it cannot leak into dst
1103 */
1104 *dst = none;
1105 } else if (class == BPF_JMP && code == BPF_CALL) {
1106 /*
1107 * at_stack_out[slot] is not cleared by the helper and subprog calls.
1108 * The fill_from_stack() may return the stale spill — which is an FP-derived arg_track
1109 * (the value that was originally spilled there). The loaded register then carries
1110 * a phantom FP-derived identity that doesn't correspond to what's actually in the slot.
1111 * This phantom FP pointer propagates forward, and wherever it's subsequently used
1112 * (as a helper argument, another store, etc.), it sets stack liveness bits.
1113 * Those bits correspond to stack accesses that don't actually happen.
1114 * So the effect is over-reporting stack liveness — marking slots as live that aren't
1115 * actually accessed. The verifier preserves more state than necessary across calls,
1116 * which is conservative.
1117 *
1118 * helpers can scratch stack slots, but they won't make a valid pointer out of it.
1119 * subprogs are allowed to write into parent slots, but they cannot write
1120 * _any_ FP-derived pointer into it (either their own or parent's FP).
1121 */
1122 for (r = BPF_REG_0; r <= BPF_REG_5; r++)
1123 at_out[r] = none;
1124 } else if (class == BPF_LDX) {
1125 u32 sz = bpf_size_to_bytes(BPF_SIZE(insn->code));
1126 bool src_is_local_fp = can_be_local_fp(depth, insn->src_reg, src);
1127
1128 /*
1129 * Reload from callee stack: if src is current-frame FP-derived
1130 * and the load is an 8-byte BPF_MEM, try to restore the spill
1131 * identity. For imprecise sources fill_from_stack() returns
1132 * ARG_IMPRECISE (off_cnt == 0).
1133 */
1134 if (src_is_local_fp && BPF_MODE(insn->code) == BPF_MEM && sz == 8) {
1135 *dst = fill_from_stack(insn, at_out, insn->src_reg, at_stack_out, depth);
1136 } else if (src->frame >= 0 && src->frame < depth &&
1137 BPF_MODE(insn->code) == BPF_MEM && sz == 8) {
1138 struct arg_track *parent_stack =
1139 env->callsite_at_stack[callsites[src->frame]];
1140
1141 *dst = fill_from_stack(insn, at_out, insn->src_reg,
1142 parent_stack, src->frame);
1143 } else if (src->frame == ARG_IMPRECISE &&
1144 !(src->mask & BIT(depth)) && src->mask &&
1145 BPF_MODE(insn->code) == BPF_MEM && sz == 8) {
1146 /*
1147 * Imprecise src with only parent-frame bits:
1148 * conservative fallback.
1149 */
1150 *dst = *src;
1151 } else {
1152 *dst = none;
1153 }
1154 } else if (class == BPF_LD && BPF_MODE(insn->code) == BPF_IMM) {
1155 *dst = none;
1156 } else if (class == BPF_STX) {
1157 u32 sz = bpf_size_to_bytes(BPF_SIZE(insn->code));
1158 bool dst_is_local_fp;
1159
1160 /* Track spills to current-frame FP-derived callee stack */
1161 dst_is_local_fp = can_be_local_fp(depth, insn->dst_reg, dst);
1162 if (dst_is_local_fp && BPF_MODE(insn->code) == BPF_MEM)
1163 spill_to_stack(insn, at_out, insn->dst_reg,
1164 at_stack_out, src, sz);
1165
1166 if (BPF_MODE(insn->code) == BPF_ATOMIC) {
1167 if (dst_is_local_fp && insn->imm != BPF_LOAD_ACQ)
1168 clear_stack_for_all_offs(insn, at_out, insn->dst_reg,
1169 at_stack_out, sz);
1170
1171 if (insn->imm == BPF_CMPXCHG)
1172 at_out[BPF_REG_0] = none;
1173 else if (insn->imm == BPF_LOAD_ACQ)
1174 *dst = none;
1175 else if (insn->imm & BPF_FETCH)
1176 *src = none;
1177 }
1178 } else if (class == BPF_ST && BPF_MODE(insn->code) == BPF_MEM) {
1179 u32 sz = bpf_size_to_bytes(BPF_SIZE(insn->code));
1180 bool dst_is_local_fp = can_be_local_fp(depth, insn->dst_reg, dst);
1181
1182 /* BPF_ST to FP-derived dst: clear overlapping stack slots */
1183 if (dst_is_local_fp)
1184 clear_stack_for_all_offs(insn, at_out, insn->dst_reg,
1185 at_stack_out, sz);
1186 }
1187 }
1188
1189 /*
1190 * Record access_bytes from helper/kfunc or load/store insn.
1191 * access_bytes > 0: stack read
1192 * access_bytes < 0: stack write
1193 * access_bytes == S64_MIN: unknown — conservative, mark [0..slot] as read
1194 * access_bytes == 0: no access
1195 *
1196 */
record_stack_access_off(struct func_instance * instance,s64 fp_off,s64 access_bytes,u32 frame,u32 insn_idx)1197 static int record_stack_access_off(struct func_instance *instance, s64 fp_off,
1198 s64 access_bytes, u32 frame, u32 insn_idx)
1199 {
1200 s32 slot_hi, slot_lo;
1201 spis_t mask;
1202
1203 if (fp_off >= 0)
1204 /*
1205 * out of bounds stack access doesn't contribute
1206 * into actual stack liveness. It will be rejected
1207 * by the main verifier pass later.
1208 */
1209 return 0;
1210 if (access_bytes == S64_MIN) {
1211 /* helper/kfunc read unknown amount of bytes from fp_off until fp+0 */
1212 slot_hi = (-fp_off - 1) / STACK_SLOT_SZ;
1213 mask = SPIS_ZERO;
1214 spis_or_range(&mask, 0, slot_hi);
1215 return mark_stack_read(instance, frame, insn_idx, mask);
1216 }
1217 if (access_bytes > 0) {
1218 /* Mark any touched slot as use */
1219 slot_hi = (-fp_off - 1) / STACK_SLOT_SZ;
1220 slot_lo = max_t(s32, (-fp_off - access_bytes) / STACK_SLOT_SZ, 0);
1221 mask = SPIS_ZERO;
1222 spis_or_range(&mask, slot_lo, slot_hi);
1223 return mark_stack_read(instance, frame, insn_idx, mask);
1224 } else if (access_bytes < 0) {
1225 /* Mark only fully covered slots as def */
1226 access_bytes = -access_bytes;
1227 slot_hi = (-fp_off) / STACK_SLOT_SZ - 1;
1228 slot_lo = max_t(s32, (-fp_off - access_bytes + STACK_SLOT_SZ - 1) / STACK_SLOT_SZ, 0);
1229 if (slot_lo <= slot_hi) {
1230 mask = SPIS_ZERO;
1231 spis_or_range(&mask, slot_lo, slot_hi);
1232 return mark_stack_write(instance, frame, insn_idx, mask);
1233 }
1234 }
1235 return 0;
1236 }
1237
1238 /*
1239 * 'arg' is FP-derived argument to helper/kfunc or load/store that
1240 * reads (positive) or writes (negative) 'access_bytes' into 'use' or 'def'.
1241 */
record_stack_access(struct func_instance * instance,const struct arg_track * arg,s64 access_bytes,u32 frame,u32 insn_idx)1242 static int record_stack_access(struct func_instance *instance,
1243 const struct arg_track *arg,
1244 s64 access_bytes, u32 frame, u32 insn_idx)
1245 {
1246 int i, err;
1247
1248 if (access_bytes == 0)
1249 return 0;
1250 if (arg->off_cnt == 0) {
1251 if (access_bytes > 0 || access_bytes == S64_MIN)
1252 return mark_stack_read(instance, frame, insn_idx, SPIS_ALL);
1253 return 0;
1254 }
1255 if (access_bytes != S64_MIN && access_bytes < 0 && arg->off_cnt != 1)
1256 /* multi-offset write cannot set stack_def */
1257 return 0;
1258
1259 for (i = 0; i < arg->off_cnt; i++) {
1260 err = record_stack_access_off(instance, arg->off[i], access_bytes, frame, insn_idx);
1261 if (err)
1262 return err;
1263 }
1264 return 0;
1265 }
1266
1267 /*
1268 * When a pointer is ARG_IMPRECISE, conservatively mark every frame in
1269 * the bitmask as fully used.
1270 */
record_imprecise(struct func_instance * instance,u32 mask,u32 insn_idx)1271 static int record_imprecise(struct func_instance *instance, u32 mask, u32 insn_idx)
1272 {
1273 int depth = instance->depth;
1274 int f, err;
1275
1276 for (f = 0; mask; f++, mask >>= 1) {
1277 if (!(mask & 1))
1278 continue;
1279 if (f <= depth) {
1280 err = mark_stack_read(instance, f, insn_idx, SPIS_ALL);
1281 if (err)
1282 return err;
1283 }
1284 }
1285 return 0;
1286 }
1287
1288 /* Record load/store access for a given 'at' state of 'insn'. */
record_load_store_access(struct bpf_verifier_env * env,struct func_instance * instance,struct arg_track * at,int insn_idx)1289 static int record_load_store_access(struct bpf_verifier_env *env,
1290 struct func_instance *instance,
1291 struct arg_track *at, int insn_idx)
1292 {
1293 struct bpf_insn *insn = &env->prog->insnsi[insn_idx];
1294 int depth = instance->depth;
1295 s32 sz = bpf_size_to_bytes(BPF_SIZE(insn->code));
1296 u8 class = BPF_CLASS(insn->code);
1297 struct arg_track resolved, *ptr;
1298 int oi;
1299
1300 switch (class) {
1301 case BPF_LDX:
1302 ptr = &at[insn->src_reg];
1303 break;
1304 case BPF_STX:
1305 if (BPF_MODE(insn->code) == BPF_ATOMIC) {
1306 if (insn->imm == BPF_STORE_REL)
1307 sz = -sz;
1308 if (insn->imm == BPF_LOAD_ACQ)
1309 ptr = &at[insn->src_reg];
1310 else
1311 ptr = &at[insn->dst_reg];
1312 } else {
1313 ptr = &at[insn->dst_reg];
1314 sz = -sz;
1315 }
1316 break;
1317 case BPF_ST:
1318 ptr = &at[insn->dst_reg];
1319 sz = -sz;
1320 break;
1321 default:
1322 return 0;
1323 }
1324
1325 /* Resolve offsets: fold insn->off into arg_track */
1326 if (ptr->off_cnt > 0) {
1327 resolved.off_cnt = ptr->off_cnt;
1328 resolved.frame = ptr->frame;
1329 for (oi = 0; oi < ptr->off_cnt; oi++) {
1330 if (arg_add(ptr->off[oi], insn->off, &resolved.off[oi])) {
1331 resolved.off_cnt = 0;
1332 break;
1333 }
1334 }
1335 ptr = &resolved;
1336 }
1337
1338 if (ptr->frame >= 0 && ptr->frame <= depth)
1339 return record_stack_access(instance, ptr, sz, ptr->frame, insn_idx);
1340 if (ptr->frame == ARG_IMPRECISE)
1341 return record_imprecise(instance, ptr->mask, insn_idx);
1342 /* ARG_NONE: not derived from any frame pointer, skip */
1343 return 0;
1344 }
1345
1346 /* Record stack access for a given 'at' state of helper/kfunc 'insn' */
record_call_access(struct bpf_verifier_env * env,struct func_instance * instance,struct arg_track * at,int insn_idx)1347 static int record_call_access(struct bpf_verifier_env *env,
1348 struct func_instance *instance,
1349 struct arg_track *at,
1350 int insn_idx)
1351 {
1352 struct bpf_insn *insn = &env->prog->insnsi[insn_idx];
1353 int depth = instance->depth;
1354 struct bpf_call_summary cs;
1355 int r, err = 0, num_params = 5;
1356
1357 if (bpf_pseudo_call(insn))
1358 return 0;
1359
1360 if (bpf_get_call_summary(env, insn, &cs))
1361 num_params = cs.num_params;
1362
1363 for (r = BPF_REG_1; r < BPF_REG_1 + num_params; r++) {
1364 int frame = at[r].frame;
1365 s64 bytes;
1366
1367 if (!arg_is_fp(&at[r]))
1368 continue;
1369
1370 if (bpf_helper_call(insn)) {
1371 bytes = bpf_helper_stack_access_bytes(env, insn, r - 1, insn_idx);
1372 } else if (bpf_pseudo_kfunc_call(insn)) {
1373 bytes = bpf_kfunc_stack_access_bytes(env, insn, r - 1, insn_idx);
1374 } else {
1375 for (int f = 0; f <= depth; f++) {
1376 err = mark_stack_read(instance, f, insn_idx, SPIS_ALL);
1377 if (err)
1378 return err;
1379 }
1380 return 0;
1381 }
1382 if (bytes == 0)
1383 continue;
1384
1385 if (frame >= 0 && frame <= depth)
1386 err = record_stack_access(instance, &at[r], bytes, frame, insn_idx);
1387 else if (frame == ARG_IMPRECISE)
1388 err = record_imprecise(instance, at[r].mask, insn_idx);
1389 if (err)
1390 return err;
1391 }
1392 return 0;
1393 }
1394
1395 /*
1396 * For a calls_callback helper, find the callback subprog and determine
1397 * which caller register maps to which callback register for FP passthrough.
1398 */
find_callback_subprog(struct bpf_verifier_env * env,struct bpf_insn * insn,int insn_idx,int * caller_reg,int * callee_reg)1399 static int find_callback_subprog(struct bpf_verifier_env *env,
1400 struct bpf_insn *insn, int insn_idx,
1401 int *caller_reg, int *callee_reg)
1402 {
1403 struct bpf_insn_aux_data *aux = &env->insn_aux_data[insn_idx];
1404 int cb_reg = -1;
1405
1406 *caller_reg = -1;
1407 *callee_reg = -1;
1408
1409 if (!bpf_helper_call(insn))
1410 return -1;
1411 switch (insn->imm) {
1412 case BPF_FUNC_loop:
1413 /* bpf_loop(nr, cb, ctx, flags): cb=R2, R3->cb R2 */
1414 cb_reg = BPF_REG_2;
1415 *caller_reg = BPF_REG_3;
1416 *callee_reg = BPF_REG_2;
1417 break;
1418 case BPF_FUNC_for_each_map_elem:
1419 /* for_each_map_elem(map, cb, ctx, flags): cb=R2, R3->cb R4 */
1420 cb_reg = BPF_REG_2;
1421 *caller_reg = BPF_REG_3;
1422 *callee_reg = BPF_REG_4;
1423 break;
1424 case BPF_FUNC_find_vma:
1425 /* find_vma(task, addr, cb, ctx, flags): cb=R3, R4->cb R3 */
1426 cb_reg = BPF_REG_3;
1427 *caller_reg = BPF_REG_4;
1428 *callee_reg = BPF_REG_3;
1429 break;
1430 case BPF_FUNC_user_ringbuf_drain:
1431 /* user_ringbuf_drain(map, cb, ctx, flags): cb=R2, R3->cb R2 */
1432 cb_reg = BPF_REG_2;
1433 *caller_reg = BPF_REG_3;
1434 *callee_reg = BPF_REG_2;
1435 break;
1436 default:
1437 return -1;
1438 }
1439
1440 if (!(aux->const_reg_subprog_mask & BIT(cb_reg)))
1441 return -2;
1442
1443 return aux->const_reg_vals[cb_reg];
1444 }
1445
1446 /* Per-subprog intermediate state kept alive across analysis phases */
1447 struct subprog_at_info {
1448 struct arg_track (*at_in)[MAX_BPF_REG];
1449 int len;
1450 };
1451
print_subprog_arg_access(struct bpf_verifier_env * env,int subprog,struct subprog_at_info * info,struct arg_track (* at_stack_in)[MAX_ARG_SPILL_SLOTS])1452 static void print_subprog_arg_access(struct bpf_verifier_env *env,
1453 int subprog,
1454 struct subprog_at_info *info,
1455 struct arg_track (*at_stack_in)[MAX_ARG_SPILL_SLOTS])
1456 {
1457 struct bpf_insn *insns = env->prog->insnsi;
1458 int start = env->subprog_info[subprog].start;
1459 int len = info->len;
1460 int i, r;
1461
1462 if (!(env->log.level & BPF_LOG_LEVEL2))
1463 return;
1464
1465 verbose(env, "%s:\n", fmt_subprog(env, subprog));
1466 for (i = 0; i < len; i++) {
1467 int idx = start + i;
1468 bool has_extra = false;
1469 u8 cls = BPF_CLASS(insns[idx].code);
1470 bool is_ldx_stx_call = cls == BPF_LDX || cls == BPF_STX ||
1471 insns[idx].code == (BPF_JMP | BPF_CALL);
1472
1473 verbose(env, "%3d: ", idx);
1474 bpf_verbose_insn(env, &insns[idx]);
1475
1476 /* Collect what needs printing */
1477 if (is_ldx_stx_call &&
1478 arg_is_visited(&info->at_in[i][0])) {
1479 for (r = 0; r < MAX_BPF_REG - 1; r++)
1480 if (arg_is_fp(&info->at_in[i][r]))
1481 has_extra = true;
1482 }
1483 if (is_ldx_stx_call) {
1484 for (r = 0; r < MAX_ARG_SPILL_SLOTS; r++)
1485 if (arg_is_fp(&at_stack_in[i][r]))
1486 has_extra = true;
1487 }
1488
1489 if (!has_extra) {
1490 if (bpf_is_ldimm64(&insns[idx]))
1491 i++;
1492 continue;
1493 }
1494
1495 bpf_vlog_reset(&env->log, env->log.end_pos - 1);
1496 verbose(env, " //");
1497
1498 if (is_ldx_stx_call && info->at_in &&
1499 arg_is_visited(&info->at_in[i][0])) {
1500 for (r = 0; r < MAX_BPF_REG - 1; r++) {
1501 if (!arg_is_fp(&info->at_in[i][r]))
1502 continue;
1503 verbose(env, " r%d=", r);
1504 verbose_arg_track(env, &info->at_in[i][r]);
1505 }
1506 }
1507
1508 if (is_ldx_stx_call) {
1509 for (r = 0; r < MAX_ARG_SPILL_SLOTS; r++) {
1510 if (!arg_is_fp(&at_stack_in[i][r]))
1511 continue;
1512 verbose(env, " fp%+d=", -(r + 1) * 8);
1513 verbose_arg_track(env, &at_stack_in[i][r]);
1514 }
1515 }
1516
1517 verbose(env, "\n");
1518 if (bpf_is_ldimm64(&insns[idx]))
1519 i++;
1520 }
1521 }
1522
1523 /*
1524 * Compute arg tracking dataflow for a single subprog.
1525 * Runs forward fixed-point with arg_track_xfer(), then records
1526 * memory accesses in a single linear pass over converged state.
1527 *
1528 * @callee_entry: pre-populated entry state for R1-R5
1529 * NULL for main (subprog 0).
1530 * @info: stores at_in, len for debug printing.
1531 */
compute_subprog_args(struct bpf_verifier_env * env,struct subprog_at_info * info,struct arg_track * callee_entry,struct func_instance * instance,u32 * callsites)1532 static int compute_subprog_args(struct bpf_verifier_env *env,
1533 struct subprog_at_info *info,
1534 struct arg_track *callee_entry,
1535 struct func_instance *instance,
1536 u32 *callsites)
1537 {
1538 int subprog = instance->subprog;
1539 struct bpf_insn *insns = env->prog->insnsi;
1540 int depth = instance->depth;
1541 int start = env->subprog_info[subprog].start;
1542 int po_start = env->subprog_info[subprog].postorder_start;
1543 int end = env->subprog_info[subprog + 1].start;
1544 int po_end = env->subprog_info[subprog + 1].postorder_start;
1545 int len = end - start;
1546 struct arg_track (*at_in)[MAX_BPF_REG] = NULL;
1547 struct arg_track at_out[MAX_BPF_REG];
1548 struct arg_track (*at_stack_in)[MAX_ARG_SPILL_SLOTS] = NULL;
1549 struct arg_track *at_stack_out = NULL;
1550 struct arg_track unvisited = { .frame = ARG_UNVISITED };
1551 struct arg_track none = { .frame = ARG_NONE };
1552 bool changed;
1553 int i, p, r, err = -ENOMEM;
1554
1555 at_in = kvmalloc_objs(*at_in, len, GFP_KERNEL_ACCOUNT);
1556 if (!at_in)
1557 goto err_free;
1558
1559 at_stack_in = kvmalloc_objs(*at_stack_in, len, GFP_KERNEL_ACCOUNT);
1560 if (!at_stack_in)
1561 goto err_free;
1562
1563 at_stack_out = kvmalloc_objs(*at_stack_out, MAX_ARG_SPILL_SLOTS, GFP_KERNEL_ACCOUNT);
1564 if (!at_stack_out)
1565 goto err_free;
1566
1567 for (i = 0; i < len; i++) {
1568 for (r = 0; r < MAX_BPF_REG; r++)
1569 at_in[i][r] = unvisited;
1570 for (r = 0; r < MAX_ARG_SPILL_SLOTS; r++)
1571 at_stack_in[i][r] = unvisited;
1572 }
1573
1574 for (r = 0; r < MAX_BPF_REG; r++)
1575 at_in[0][r] = none;
1576
1577 /* Entry: R10 is always precisely the current frame's FP */
1578 at_in[0][BPF_REG_FP] = arg_single(depth, 0);
1579
1580 /* R1-R5: from caller or ARG_NONE for main */
1581 if (callee_entry) {
1582 for (r = BPF_REG_1; r <= BPF_REG_5; r++)
1583 at_in[0][r] = callee_entry[r];
1584 }
1585
1586 /* Entry: all stack slots are ARG_NONE */
1587 for (r = 0; r < MAX_ARG_SPILL_SLOTS; r++)
1588 at_stack_in[0][r] = none;
1589
1590 if (env->log.level & BPF_LOG_LEVEL2)
1591 verbose(env, "subprog#%d: analyzing (depth %d)...\n", subprog, depth);
1592
1593 /* Forward fixed-point iteration in reverse post order */
1594 redo:
1595 changed = false;
1596 for (p = po_end - 1; p >= po_start; p--) {
1597 int idx = env->cfg.insn_postorder[p];
1598 int i = idx - start;
1599 struct bpf_insn *insn = &insns[idx];
1600 struct bpf_iarray *succ;
1601
1602 if (!arg_is_visited(&at_in[i][0]) && !arg_is_visited(&at_in[i][1]))
1603 continue;
1604
1605 memcpy(at_out, at_in[i], sizeof(at_out));
1606 memcpy(at_stack_out, at_stack_in[i], MAX_ARG_SPILL_SLOTS * sizeof(*at_stack_out));
1607
1608 arg_track_xfer(env, insn, idx, at_out, at_stack_out, instance, callsites);
1609 arg_track_log(env, insn, idx, at_in[i], at_stack_in[i], at_out, at_stack_out);
1610
1611 /* Propagate to successors within this subprogram */
1612 succ = bpf_insn_successors(env, idx);
1613 for (int s = 0; s < succ->cnt; s++) {
1614 int target = succ->items[s];
1615 int ti;
1616
1617 /* Filter: stay within the subprogram's range */
1618 if (target < start || target >= end)
1619 continue;
1620 ti = target - start;
1621
1622 for (r = 0; r < MAX_BPF_REG; r++)
1623 changed |= arg_track_join(env, idx, target, r,
1624 &at_in[ti][r], at_out[r]);
1625
1626 for (r = 0; r < MAX_ARG_SPILL_SLOTS; r++)
1627 changed |= arg_track_join(env, idx, target, -r - 1,
1628 &at_stack_in[ti][r], at_stack_out[r]);
1629 }
1630 }
1631 if (changed)
1632 goto redo;
1633
1634 /* Record memory accesses using converged at_in (RPO skips dead code) */
1635 for (p = po_end - 1; p >= po_start; p--) {
1636 int idx = env->cfg.insn_postorder[p];
1637 int i = idx - start;
1638 struct bpf_insn *insn = &insns[idx];
1639
1640 err = record_load_store_access(env, instance, at_in[i], idx);
1641 if (err)
1642 goto err_free;
1643
1644 if (insn->code == (BPF_JMP | BPF_CALL)) {
1645 err = record_call_access(env, instance, at_in[i], idx);
1646 if (err)
1647 goto err_free;
1648 }
1649
1650 if (bpf_pseudo_call(insn) || bpf_calls_callback(env, idx)) {
1651 kvfree(env->callsite_at_stack[idx]);
1652 env->callsite_at_stack[idx] =
1653 kvmalloc_objs(*env->callsite_at_stack[idx],
1654 MAX_ARG_SPILL_SLOTS, GFP_KERNEL_ACCOUNT);
1655 if (!env->callsite_at_stack[idx]) {
1656 err = -ENOMEM;
1657 goto err_free;
1658 }
1659 memcpy(env->callsite_at_stack[idx],
1660 at_stack_in[i], sizeof(struct arg_track) * MAX_ARG_SPILL_SLOTS);
1661 }
1662 }
1663
1664 info->at_in = at_in;
1665 at_in = NULL;
1666 info->len = len;
1667 print_subprog_arg_access(env, subprog, info, at_stack_in);
1668 err = 0;
1669
1670 err_free:
1671 kvfree(at_stack_out);
1672 kvfree(at_stack_in);
1673 kvfree(at_in);
1674 return err;
1675 }
1676
1677 /* Return true if any of R1-R5 is derived from a frame pointer. */
has_fp_args(struct arg_track * args)1678 static bool has_fp_args(struct arg_track *args)
1679 {
1680 for (int r = BPF_REG_1; r <= BPF_REG_5; r++)
1681 if (args[r].frame != ARG_NONE)
1682 return true;
1683 return false;
1684 }
1685
1686 /*
1687 * Merge a freshly analyzed instance into the original.
1688 * may_read: union (any pass might read the slot).
1689 * must_write: intersection (only slots written on ALL passes are guaranteed).
1690 * live_before is recomputed by a subsequent update_instance() on @dst.
1691 */
merge_instances(struct func_instance * dst,struct func_instance * src)1692 static void merge_instances(struct func_instance *dst, struct func_instance *src)
1693 {
1694 int f, i;
1695
1696 for (f = 0; f <= dst->depth; f++) {
1697 if (!src->frames[f]) {
1698 /* This pass didn't touch frame f — must_write intersects with empty. */
1699 if (dst->frames[f])
1700 for (i = 0; i < dst->insn_cnt; i++)
1701 dst->frames[f][i].must_write = SPIS_ZERO;
1702 continue;
1703 }
1704 if (!dst->frames[f]) {
1705 /* Previous pass didn't touch frame f — take src, zero must_write. */
1706 dst->frames[f] = src->frames[f];
1707 src->frames[f] = NULL;
1708 for (i = 0; i < dst->insn_cnt; i++)
1709 dst->frames[f][i].must_write = SPIS_ZERO;
1710 continue;
1711 }
1712 for (i = 0; i < dst->insn_cnt; i++) {
1713 dst->frames[f][i].may_read =
1714 spis_or(dst->frames[f][i].may_read,
1715 src->frames[f][i].may_read);
1716 dst->frames[f][i].must_write =
1717 spis_and(dst->frames[f][i].must_write,
1718 src->frames[f][i].must_write);
1719 }
1720 }
1721 }
1722
fresh_instance(struct func_instance * src)1723 static struct func_instance *fresh_instance(struct func_instance *src)
1724 {
1725 struct func_instance *f;
1726
1727 f = kvzalloc_obj(*f, GFP_KERNEL_ACCOUNT);
1728 if (!f)
1729 return ERR_PTR(-ENOMEM);
1730 f->callsite = src->callsite;
1731 f->depth = src->depth;
1732 f->subprog = src->subprog;
1733 f->subprog_start = src->subprog_start;
1734 f->insn_cnt = src->insn_cnt;
1735 return f;
1736 }
1737
free_instance(struct func_instance * instance)1738 static void free_instance(struct func_instance *instance)
1739 {
1740 int i;
1741
1742 for (i = 0; i <= instance->depth; i++)
1743 kvfree(instance->frames[i]);
1744 kvfree(instance);
1745 }
1746
1747 /*
1748 * Recursively analyze a subprog with specific 'entry_args'.
1749 * Each callee is analyzed with the exact args from its call site.
1750 *
1751 * Args are recomputed for each call because the dataflow result at_in[]
1752 * depends on the entry args and frame depth. Consider: A->C->D and B->C->D
1753 * Callsites in A and B pass different args into C, so C is recomputed.
1754 * Then within C the same callsite passes different args into D.
1755 */
analyze_subprog(struct bpf_verifier_env * env,struct arg_track * entry_args,struct subprog_at_info * info,struct func_instance * instance,u32 * callsites)1756 static int analyze_subprog(struct bpf_verifier_env *env,
1757 struct arg_track *entry_args,
1758 struct subprog_at_info *info,
1759 struct func_instance *instance,
1760 u32 *callsites)
1761 {
1762 int subprog = instance->subprog;
1763 int depth = instance->depth;
1764 struct bpf_insn *insns = env->prog->insnsi;
1765 int start = env->subprog_info[subprog].start;
1766 int po_start = env->subprog_info[subprog].postorder_start;
1767 int po_end = env->subprog_info[subprog + 1].postorder_start;
1768 struct func_instance *prev_instance = NULL;
1769 int j, err;
1770
1771 if (++env->liveness->subprog_calls > 10000) {
1772 verbose(env, "liveness analysis exceeded complexity limit (%d calls)\n",
1773 env->liveness->subprog_calls);
1774 return -E2BIG;
1775 }
1776
1777 if (need_resched())
1778 cond_resched();
1779
1780
1781 /*
1782 * When an instance is reused (must_write_initialized == true),
1783 * record into a fresh instance and merge afterward. This avoids
1784 * stale must_write marks for instructions not reached in this pass.
1785 */
1786 if (instance->must_write_initialized) {
1787 struct func_instance *fresh = fresh_instance(instance);
1788
1789 if (IS_ERR(fresh))
1790 return PTR_ERR(fresh);
1791 prev_instance = instance;
1792 instance = fresh;
1793 }
1794
1795 /* Free prior analysis if this subprog was already visited */
1796 kvfree(info[subprog].at_in);
1797 info[subprog].at_in = NULL;
1798
1799 err = compute_subprog_args(env, &info[subprog], entry_args, instance, callsites);
1800 if (err)
1801 goto out_free;
1802
1803 /* For each reachable call site in the subprog, recurse into callees */
1804 for (int p = po_start; p < po_end; p++) {
1805 int idx = env->cfg.insn_postorder[p];
1806 struct arg_track callee_args[BPF_REG_5 + 1];
1807 struct arg_track none = { .frame = ARG_NONE };
1808 struct bpf_insn *insn = &insns[idx];
1809 struct func_instance *callee_instance;
1810 int callee, target;
1811 int caller_reg, cb_callee_reg;
1812
1813 j = idx - start; /* relative index within this subprog */
1814
1815 if (bpf_pseudo_call(insn)) {
1816 target = idx + insn->imm + 1;
1817 callee = bpf_find_subprog(env, target);
1818 if (callee < 0)
1819 continue;
1820
1821 /* Build entry args: R1-R5 from at_in at call site */
1822 for (int r = BPF_REG_1; r <= BPF_REG_5; r++)
1823 callee_args[r] = info[subprog].at_in[j][r];
1824 } else if (bpf_calls_callback(env, idx)) {
1825 callee = find_callback_subprog(env, insn, idx, &caller_reg, &cb_callee_reg);
1826 if (callee == -2) {
1827 /*
1828 * same bpf_loop() calls two different callbacks and passes
1829 * stack pointer to them
1830 */
1831 if (info[subprog].at_in[j][caller_reg].frame == ARG_NONE)
1832 continue;
1833 for (int f = 0; f <= depth; f++) {
1834 err = mark_stack_read(instance, f, idx, SPIS_ALL);
1835 if (err)
1836 goto out_free;
1837 }
1838 continue;
1839 }
1840 if (callee < 0)
1841 continue;
1842
1843 for (int r = BPF_REG_1; r <= BPF_REG_5; r++)
1844 callee_args[r] = none;
1845 callee_args[cb_callee_reg] = info[subprog].at_in[j][caller_reg];
1846 } else {
1847 continue;
1848 }
1849
1850 if (!has_fp_args(callee_args))
1851 continue;
1852
1853 if (depth == MAX_CALL_FRAMES - 1) {
1854 err = -EINVAL;
1855 goto out_free;
1856 }
1857
1858 callee_instance = call_instance(env, instance, idx, callee);
1859 if (IS_ERR(callee_instance)) {
1860 err = PTR_ERR(callee_instance);
1861 goto out_free;
1862 }
1863 callsites[depth] = idx;
1864 err = analyze_subprog(env, callee_args, info, callee_instance, callsites);
1865 if (err)
1866 goto out_free;
1867
1868 /* Pull callee's entry liveness back to caller's callsite */
1869 {
1870 u32 callee_start = callee_instance->subprog_start;
1871 struct per_frame_masks *entry;
1872
1873 for (int f = 0; f < callee_instance->depth; f++) {
1874 entry = get_frame_masks(callee_instance, f, callee_start);
1875 if (!entry)
1876 continue;
1877 err = mark_stack_read(instance, f, idx, entry->live_before);
1878 if (err)
1879 goto out_free;
1880 }
1881 }
1882 }
1883
1884 if (prev_instance) {
1885 merge_instances(prev_instance, instance);
1886 free_instance(instance);
1887 instance = prev_instance;
1888 }
1889 update_instance(env, instance);
1890 return 0;
1891
1892 out_free:
1893 if (prev_instance)
1894 free_instance(instance);
1895 return err;
1896 }
1897
bpf_compute_subprog_arg_access(struct bpf_verifier_env * env)1898 int bpf_compute_subprog_arg_access(struct bpf_verifier_env *env)
1899 {
1900 u32 callsites[MAX_CALL_FRAMES] = {};
1901 int insn_cnt = env->prog->len;
1902 struct func_instance *instance;
1903 struct subprog_at_info *info;
1904 int k, err = 0;
1905
1906 info = kvzalloc_objs(*info, env->subprog_cnt, GFP_KERNEL_ACCOUNT);
1907 if (!info)
1908 return -ENOMEM;
1909
1910 env->callsite_at_stack = kvzalloc_objs(*env->callsite_at_stack, insn_cnt,
1911 GFP_KERNEL_ACCOUNT);
1912 if (!env->callsite_at_stack) {
1913 kvfree(info);
1914 return -ENOMEM;
1915 }
1916
1917 /*
1918 * Analyze every subprog in reverse topological order (callers
1919 * before callees) so that each subprog is analyzed before its
1920 * callees, allowing the recursive walk inside analyze_subprog()
1921 * to naturally reach callees that receive FP-derived args.
1922 *
1923 * Subprogs and callbacks that don't receive FP-derived arguments
1924 * cannot access ancestor stack frames are analyzed independently.
1925 * Async callbacks (timer, workqueue) are handled the same way.
1926 */
1927 for (k = env->subprog_cnt - 1; k >= 0; k--) {
1928 int sub = env->subprog_topo_order[k];
1929
1930 if (info[sub].at_in && !bpf_subprog_is_global(env, sub))
1931 continue;
1932 instance = call_instance(env, NULL, 0, sub);
1933 if (IS_ERR(instance)) {
1934 err = PTR_ERR(instance);
1935 goto out;
1936 }
1937 err = analyze_subprog(env, NULL, info, instance, callsites);
1938 if (err)
1939 goto out;
1940 }
1941
1942 if (env->log.level & BPF_LOG_LEVEL2)
1943 err = print_instances(env);
1944
1945 out:
1946 for (k = 0; k < insn_cnt; k++)
1947 kvfree(env->callsite_at_stack[k]);
1948 kvfree(env->callsite_at_stack);
1949 env->callsite_at_stack = NULL;
1950 for (k = 0; k < env->subprog_cnt; k++)
1951 kvfree(info[k].at_in);
1952 kvfree(info);
1953 return err;
1954 }
1955
1956 /* Each field is a register bitmask */
1957 struct insn_live_regs {
1958 u16 use; /* registers read by instruction */
1959 u16 def; /* registers written by instruction */
1960 u16 in; /* registers that may be alive before instruction */
1961 u16 out; /* registers that may be alive after instruction */
1962 };
1963
1964 /* Bitmask with 1s for all caller saved registers */
1965 #define ALL_CALLER_SAVED_REGS ((1u << CALLER_SAVED_REGS) - 1)
1966
1967 /* Compute info->{use,def} fields for the instruction */
compute_insn_live_regs(struct bpf_verifier_env * env,struct bpf_insn * insn,struct insn_live_regs * info)1968 static void compute_insn_live_regs(struct bpf_verifier_env *env,
1969 struct bpf_insn *insn,
1970 struct insn_live_regs *info)
1971 {
1972 struct bpf_call_summary cs;
1973 u8 class = BPF_CLASS(insn->code);
1974 u8 code = BPF_OP(insn->code);
1975 u8 mode = BPF_MODE(insn->code);
1976 u16 src = BIT(insn->src_reg);
1977 u16 dst = BIT(insn->dst_reg);
1978 u16 r0 = BIT(0);
1979 u16 def = 0;
1980 u16 use = 0xffff;
1981
1982 switch (class) {
1983 case BPF_LD:
1984 switch (mode) {
1985 case BPF_IMM:
1986 if (BPF_SIZE(insn->code) == BPF_DW) {
1987 def = dst;
1988 use = 0;
1989 }
1990 break;
1991 case BPF_LD | BPF_ABS:
1992 case BPF_LD | BPF_IND:
1993 /* stick with defaults */
1994 break;
1995 }
1996 break;
1997 case BPF_LDX:
1998 switch (mode) {
1999 case BPF_MEM:
2000 case BPF_MEMSX:
2001 def = dst;
2002 use = src;
2003 break;
2004 }
2005 break;
2006 case BPF_ST:
2007 switch (mode) {
2008 case BPF_MEM:
2009 def = 0;
2010 use = dst;
2011 break;
2012 }
2013 break;
2014 case BPF_STX:
2015 switch (mode) {
2016 case BPF_MEM:
2017 def = 0;
2018 use = dst | src;
2019 break;
2020 case BPF_ATOMIC:
2021 switch (insn->imm) {
2022 case BPF_CMPXCHG:
2023 use = r0 | dst | src;
2024 def = r0;
2025 break;
2026 case BPF_LOAD_ACQ:
2027 def = dst;
2028 use = src;
2029 break;
2030 case BPF_STORE_REL:
2031 def = 0;
2032 use = dst | src;
2033 break;
2034 default:
2035 use = dst | src;
2036 if (insn->imm & BPF_FETCH)
2037 def = src;
2038 else
2039 def = 0;
2040 }
2041 break;
2042 }
2043 break;
2044 case BPF_ALU:
2045 case BPF_ALU64:
2046 switch (code) {
2047 case BPF_END:
2048 use = dst;
2049 def = dst;
2050 break;
2051 case BPF_MOV:
2052 def = dst;
2053 if (BPF_SRC(insn->code) == BPF_K)
2054 use = 0;
2055 else
2056 use = src;
2057 break;
2058 default:
2059 def = dst;
2060 if (BPF_SRC(insn->code) == BPF_K)
2061 use = dst;
2062 else
2063 use = dst | src;
2064 }
2065 break;
2066 case BPF_JMP:
2067 case BPF_JMP32:
2068 switch (code) {
2069 case BPF_JA:
2070 def = 0;
2071 if (BPF_SRC(insn->code) == BPF_X)
2072 use = dst;
2073 else
2074 use = 0;
2075 break;
2076 case BPF_JCOND:
2077 def = 0;
2078 use = 0;
2079 break;
2080 case BPF_EXIT:
2081 def = 0;
2082 use = r0;
2083 break;
2084 case BPF_CALL:
2085 def = ALL_CALLER_SAVED_REGS;
2086 use = def & ~BIT(BPF_REG_0);
2087 if (bpf_get_call_summary(env, insn, &cs))
2088 use = GENMASK(cs.num_params, 1);
2089 break;
2090 default:
2091 def = 0;
2092 if (BPF_SRC(insn->code) == BPF_K)
2093 use = dst;
2094 else
2095 use = dst | src;
2096 }
2097 break;
2098 }
2099
2100 info->def = def;
2101 info->use = use;
2102 }
2103
2104 /* Compute may-live registers after each instruction in the program.
2105 * The register is live after the instruction I if it is read by some
2106 * instruction S following I during program execution and is not
2107 * overwritten between I and S.
2108 *
2109 * Store result in env->insn_aux_data[i].live_regs.
2110 */
bpf_compute_live_registers(struct bpf_verifier_env * env)2111 int bpf_compute_live_registers(struct bpf_verifier_env *env)
2112 {
2113 struct bpf_insn_aux_data *insn_aux = env->insn_aux_data;
2114 struct bpf_insn *insns = env->prog->insnsi;
2115 struct insn_live_regs *state;
2116 int insn_cnt = env->prog->len;
2117 int err = 0, i, j;
2118 bool changed;
2119
2120 /* Use the following algorithm:
2121 * - define the following:
2122 * - I.use : a set of all registers read by instruction I;
2123 * - I.def : a set of all registers written by instruction I;
2124 * - I.in : a set of all registers that may be alive before I execution;
2125 * - I.out : a set of all registers that may be alive after I execution;
2126 * - insn_successors(I): a set of instructions S that might immediately
2127 * follow I for some program execution;
2128 * - associate separate empty sets 'I.in' and 'I.out' with each instruction;
2129 * - visit each instruction in a postorder and update
2130 * state[i].in, state[i].out as follows:
2131 *
2132 * state[i].out = U [state[s].in for S in insn_successors(i)]
2133 * state[i].in = (state[i].out / state[i].def) U state[i].use
2134 *
2135 * (where U stands for set union, / stands for set difference)
2136 * - repeat the computation while {in,out} fields changes for
2137 * any instruction.
2138 */
2139 state = kvzalloc_objs(*state, insn_cnt, GFP_KERNEL_ACCOUNT);
2140 if (!state) {
2141 err = -ENOMEM;
2142 goto out;
2143 }
2144
2145 for (i = 0; i < insn_cnt; ++i)
2146 compute_insn_live_regs(env, &insns[i], &state[i]);
2147
2148 /* Forward pass: resolve stack access through FP-derived pointers */
2149 err = bpf_compute_subprog_arg_access(env);
2150 if (err)
2151 goto out;
2152
2153 changed = true;
2154 while (changed) {
2155 changed = false;
2156 for (i = 0; i < env->cfg.cur_postorder; ++i) {
2157 int insn_idx = env->cfg.insn_postorder[i];
2158 struct insn_live_regs *live = &state[insn_idx];
2159 struct bpf_iarray *succ;
2160 u16 new_out = 0;
2161 u16 new_in = 0;
2162
2163 succ = bpf_insn_successors(env, insn_idx);
2164 for (int s = 0; s < succ->cnt; ++s)
2165 new_out |= state[succ->items[s]].in;
2166 new_in = (new_out & ~live->def) | live->use;
2167 if (new_out != live->out || new_in != live->in) {
2168 live->in = new_in;
2169 live->out = new_out;
2170 changed = true;
2171 }
2172 }
2173 }
2174
2175 for (i = 0; i < insn_cnt; ++i)
2176 insn_aux[i].live_regs_before = state[i].in;
2177
2178 if (env->log.level & BPF_LOG_LEVEL2) {
2179 verbose(env, "Live regs before insn:\n");
2180 for (i = 0; i < insn_cnt; ++i) {
2181 if (env->insn_aux_data[i].scc)
2182 verbose(env, "%3d ", env->insn_aux_data[i].scc);
2183 else
2184 verbose(env, " ");
2185 verbose(env, "%3d: ", i);
2186 for (j = BPF_REG_0; j < BPF_REG_10; ++j)
2187 if (insn_aux[i].live_regs_before & BIT(j))
2188 verbose(env, "%d", j);
2189 else
2190 verbose(env, ".");
2191 verbose(env, " ");
2192 bpf_verbose_insn(env, &insns[i]);
2193 if (bpf_is_ldimm64(&insns[i]))
2194 i++;
2195 }
2196 }
2197
2198 out:
2199 kvfree(state);
2200 return err;
2201 }
2202