xref: /linux/kernel/bpf/liveness.c (revision 82f78acd5a9270370ef4aa3f032ede25f3dc91ee)
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/hashtable.h>
6 #include <linux/jhash.h>
7 #include <linux/slab.h>
8 
9 /*
10  * This file implements live stack slots analysis. After accumulating
11  * stack usage data, the analysis answers queries about whether a
12  * particular stack slot may be read by an instruction or any of it's
13  * successors.  This data is consumed by the verifier states caching
14  * mechanism to decide which stack slots are important when looking for a
15  * visited state corresponding to the current state.
16  *
17  * The analysis is call chain sensitive, meaning that data is collected
18  * and queried for tuples (call chain, subprogram instruction index).
19  * Such sensitivity allows identifying if some subprogram call always
20  * leads to writes in the caller's stack.
21  *
22  * The basic idea is as follows:
23  * - As the verifier accumulates a set of visited states, the analysis instance
24  *   accumulates a conservative estimate of stack slots that can be read
25  *   or must be written for each visited tuple (call chain, instruction index).
26  * - If several states happen to visit the same instruction with the same
27  *   call chain, stack usage information for the corresponding tuple is joined:
28  *   - "may_read" set represents a union of all possibly read slots
29  *     (any slot in "may_read" set might be read at or after the instruction);
30  *   - "must_write" set represents an intersection of all possibly written slots
31  *     (any slot in "must_write" set is guaranteed to be written by the instruction).
32  * - The analysis is split into two phases:
33  *   - read and write marks accumulation;
34  *   - read and write marks propagation.
35  * - The propagation phase is a textbook live variable data flow analysis:
36  *
37  *     state[cc, i].live_after = U [state[cc, s].live_before for s in bpf_insn_successors(i)]
38  *     state[cc, i].live_before =
39  *       (state[cc, i].live_after / state[cc, i].must_write) U state[i].may_read
40  *
41  *   Where:
42  *   - `U`  stands for set union
43  *   - `/`  stands for set difference;
44  *   - `cc` stands for a call chain;
45  *   - `i` and `s` are instruction indexes;
46  *
47  *   The above equations are computed for each call chain and instruction
48  *   index until state stops changing.
49  * - Additionally, in order to transfer "must_write" information from a
50  *   subprogram to call instructions invoking this subprogram,
51  *   the "must_write_acc" set is tracked for each (cc, i) tuple.
52  *   A set of stack slots that are guaranteed to be written by this
53  *   instruction or any of its successors (within the subprogram).
54  *   The equation for "must_write_acc" propagation looks as follows:
55  *
56  *     state[cc, i].must_write_acc =
57  *       ∩ [state[cc, s].must_write_acc for s in bpf_insn_successors(i)]
58  *       U state[cc, i].must_write
59  *
60  *   (An intersection of all "must_write_acc" for instruction successors
61  *    plus all "must_write" slots for the instruction itself).
62  * - After the propagation phase completes for a subprogram, information from
63  *   (cc, 0) tuple (subprogram entry) is transferred to the caller's call chain:
64  *   - "must_write_acc" set is intersected with the call site's "must_write" set;
65  *   - "may_read" set is added to the call site's "may_read" set.
66  * - Any live stack queries must be taken after the propagation phase.
67  * - Accumulation and propagation phases can be entered multiple times,
68  *   at any point in time:
69  *   - "may_read" set only grows;
70  *   - "must_write" set only shrinks;
71  *   - for each visited verifier state with zero branches, all relevant
72  *     read and write marks are already recorded by the analysis instance.
73  *
74  * Technically, the analysis is facilitated by the following data structures:
75  * - Call chain: for given verifier state, the call chain is a tuple of call
76  *   instruction indexes leading to the current subprogram plus the subprogram
77  *   entry point index.
78  * - Function instance: for a given call chain, for each instruction in
79  *   the current subprogram, a mapping between instruction index and a
80  *   set of "may_read", "must_write" and other marks accumulated for this
81  *   instruction.
82  * - A hash table mapping call chains to function instances.
83  */
84 
85 struct callchain {
86 	u32 callsites[MAX_CALL_FRAMES];	/* instruction pointer for each frame */
87 	/* cached subprog_info[*].start for functions owning the frames:
88 	 * - sp_starts[curframe] used to get insn relative index within current function;
89 	 * - sp_starts[0..current-1] used for fast callchain_frame_up().
90 	 */
91 	u32 sp_starts[MAX_CALL_FRAMES];
92 	u32 curframe;			/* depth of callsites and sp_starts arrays */
93 };
94 
95 struct per_frame_masks {
96 	u64 may_read;		/* stack slots that may be read by this instruction */
97 	u64 must_write;		/* stack slots written by this instruction */
98 	u64 must_write_acc;	/* stack slots written by this instruction and its successors */
99 	u64 live_before;	/* stack slots that may be read by this insn and its successors */
100 };
101 
102 /*
103  * A function instance created for a specific callchain.
104  * Encapsulates read and write marks for each instruction in the function.
105  * Marks are tracked for each frame in the callchain.
106  */
107 struct func_instance {
108 	struct hlist_node hl_node;
109 	struct callchain callchain;
110 	u32 insn_cnt;		/* cached number of insns in the function */
111 	bool updated;
112 	bool must_write_dropped;
113 	/* Per frame, per instruction masks, frames allocated lazily. */
114 	struct per_frame_masks *frames[MAX_CALL_FRAMES];
115 	/* For each instruction a flag telling if "must_write" had been initialized for it. */
116 	bool *must_write_set;
117 };
118 
119 struct live_stack_query {
120 	struct func_instance *instances[MAX_CALL_FRAMES]; /* valid in range [0..curframe] */
121 	u32 curframe;
122 	u32 insn_idx;
123 };
124 
125 struct bpf_liveness {
126 	DECLARE_HASHTABLE(func_instances, 8);		/* maps callchain to func_instance */
127 	struct live_stack_query live_stack_query;	/* cache to avoid repetitive ht lookups */
128 	/* Cached instance corresponding to env->cur_state, avoids per-instruction ht lookup */
129 	struct func_instance *cur_instance;
130 	/*
131 	 * Below fields are used to accumulate stack write marks for instruction at
132 	 * @write_insn_idx before submitting the marks to @cur_instance.
133 	 */
134 	u64 write_masks_acc[MAX_CALL_FRAMES];
135 	u32 write_insn_idx;
136 };
137 
138 /* Compute callchain corresponding to state @st at depth @frameno */
compute_callchain(struct bpf_verifier_env * env,struct bpf_verifier_state * st,struct callchain * callchain,u32 frameno)139 static void compute_callchain(struct bpf_verifier_env *env, struct bpf_verifier_state *st,
140 			      struct callchain *callchain, u32 frameno)
141 {
142 	struct bpf_subprog_info *subprog_info = env->subprog_info;
143 	u32 i;
144 
145 	memset(callchain, 0, sizeof(*callchain));
146 	for (i = 0; i <= frameno; i++) {
147 		callchain->sp_starts[i] = subprog_info[st->frame[i]->subprogno].start;
148 		if (i < st->curframe)
149 			callchain->callsites[i] = st->frame[i + 1]->callsite;
150 	}
151 	callchain->curframe = frameno;
152 	callchain->callsites[callchain->curframe] = callchain->sp_starts[callchain->curframe];
153 }
154 
hash_callchain(struct callchain * callchain)155 static u32 hash_callchain(struct callchain *callchain)
156 {
157 	return jhash2(callchain->callsites, callchain->curframe, 0);
158 }
159 
same_callsites(struct callchain * a,struct callchain * b)160 static bool same_callsites(struct callchain *a, struct callchain *b)
161 {
162 	int i;
163 
164 	if (a->curframe != b->curframe)
165 		return false;
166 	for (i = a->curframe; i >= 0; i--)
167 		if (a->callsites[i] != b->callsites[i])
168 			return false;
169 	return true;
170 }
171 
172 /*
173  * Find existing or allocate new function instance corresponding to @callchain.
174  * Instances are accumulated in env->liveness->func_instances and persist
175  * until the end of the verification process.
176  */
__lookup_instance(struct bpf_verifier_env * env,struct callchain * callchain)177 static struct func_instance *__lookup_instance(struct bpf_verifier_env *env,
178 					       struct callchain *callchain)
179 {
180 	struct bpf_liveness *liveness = env->liveness;
181 	struct bpf_subprog_info *subprog;
182 	struct func_instance *result;
183 	u32 subprog_sz, size, key;
184 
185 	key = hash_callchain(callchain);
186 	hash_for_each_possible(liveness->func_instances, result, hl_node, key)
187 		if (same_callsites(&result->callchain, callchain))
188 			return result;
189 
190 	subprog = bpf_find_containing_subprog(env, callchain->sp_starts[callchain->curframe]);
191 	subprog_sz = (subprog + 1)->start - subprog->start;
192 	size = sizeof(struct func_instance);
193 	result = kvzalloc(size, GFP_KERNEL_ACCOUNT);
194 	if (!result)
195 		return ERR_PTR(-ENOMEM);
196 	result->must_write_set = kvcalloc(subprog_sz, sizeof(*result->must_write_set),
197 					  GFP_KERNEL_ACCOUNT);
198 	if (!result->must_write_set) {
199 		kvfree(result);
200 		return ERR_PTR(-ENOMEM);
201 	}
202 	memcpy(&result->callchain, callchain, sizeof(*callchain));
203 	result->insn_cnt = subprog_sz;
204 	hash_add(liveness->func_instances, &result->hl_node, key);
205 	return result;
206 }
207 
lookup_instance(struct bpf_verifier_env * env,struct bpf_verifier_state * st,u32 frameno)208 static struct func_instance *lookup_instance(struct bpf_verifier_env *env,
209 					     struct bpf_verifier_state *st,
210 					     u32 frameno)
211 {
212 	struct callchain callchain;
213 
214 	compute_callchain(env, st, &callchain, frameno);
215 	return __lookup_instance(env, &callchain);
216 }
217 
bpf_stack_liveness_init(struct bpf_verifier_env * env)218 int bpf_stack_liveness_init(struct bpf_verifier_env *env)
219 {
220 	env->liveness = kvzalloc(sizeof(*env->liveness), GFP_KERNEL_ACCOUNT);
221 	if (!env->liveness)
222 		return -ENOMEM;
223 	hash_init(env->liveness->func_instances);
224 	return 0;
225 }
226 
bpf_stack_liveness_free(struct bpf_verifier_env * env)227 void bpf_stack_liveness_free(struct bpf_verifier_env *env)
228 {
229 	struct func_instance *instance;
230 	struct hlist_node *tmp;
231 	int bkt, i;
232 
233 	if (!env->liveness)
234 		return;
235 	hash_for_each_safe(env->liveness->func_instances, bkt, tmp, instance, hl_node) {
236 		for (i = 0; i <= instance->callchain.curframe; i++)
237 			kvfree(instance->frames[i]);
238 		kvfree(instance->must_write_set);
239 		kvfree(instance);
240 	}
241 	kvfree(env->liveness);
242 }
243 
244 /*
245  * Convert absolute instruction index @insn_idx to an index relative
246  * to start of the function corresponding to @instance.
247  */
relative_idx(struct func_instance * instance,u32 insn_idx)248 static int relative_idx(struct func_instance *instance, u32 insn_idx)
249 {
250 	return insn_idx - instance->callchain.sp_starts[instance->callchain.curframe];
251 }
252 
get_frame_masks(struct func_instance * instance,u32 frame,u32 insn_idx)253 static struct per_frame_masks *get_frame_masks(struct func_instance *instance,
254 					       u32 frame, u32 insn_idx)
255 {
256 	if (!instance->frames[frame])
257 		return NULL;
258 
259 	return &instance->frames[frame][relative_idx(instance, insn_idx)];
260 }
261 
alloc_frame_masks(struct bpf_verifier_env * env,struct func_instance * instance,u32 frame,u32 insn_idx)262 static struct per_frame_masks *alloc_frame_masks(struct bpf_verifier_env *env,
263 						 struct func_instance *instance,
264 						 u32 frame, u32 insn_idx)
265 {
266 	struct per_frame_masks *arr;
267 
268 	if (!instance->frames[frame]) {
269 		arr = kvcalloc(instance->insn_cnt, sizeof(*arr), GFP_KERNEL_ACCOUNT);
270 		instance->frames[frame] = arr;
271 		if (!arr)
272 			return ERR_PTR(-ENOMEM);
273 	}
274 	return get_frame_masks(instance, frame, insn_idx);
275 }
276 
bpf_reset_live_stack_callchain(struct bpf_verifier_env * env)277 void bpf_reset_live_stack_callchain(struct bpf_verifier_env *env)
278 {
279 	env->liveness->cur_instance = NULL;
280 }
281 
282 /* If @env->liveness->cur_instance is null, set it to instance corresponding to @env->cur_state. */
ensure_cur_instance(struct bpf_verifier_env * env)283 static int ensure_cur_instance(struct bpf_verifier_env *env)
284 {
285 	struct bpf_liveness *liveness = env->liveness;
286 	struct func_instance *instance;
287 
288 	if (liveness->cur_instance)
289 		return 0;
290 
291 	instance = lookup_instance(env, env->cur_state, env->cur_state->curframe);
292 	if (IS_ERR(instance))
293 		return PTR_ERR(instance);
294 
295 	liveness->cur_instance = instance;
296 	return 0;
297 }
298 
299 /* Accumulate may_read masks for @frame at @insn_idx */
mark_stack_read(struct bpf_verifier_env * env,struct func_instance * instance,u32 frame,u32 insn_idx,u64 mask)300 static int mark_stack_read(struct bpf_verifier_env *env,
301 			   struct func_instance *instance, u32 frame, u32 insn_idx, u64 mask)
302 {
303 	struct per_frame_masks *masks;
304 	u64 new_may_read;
305 
306 	masks = alloc_frame_masks(env, instance, frame, insn_idx);
307 	if (IS_ERR(masks))
308 		return PTR_ERR(masks);
309 	new_may_read = masks->may_read | mask;
310 	if (new_may_read != masks->may_read &&
311 	    ((new_may_read | masks->live_before) != masks->live_before))
312 		instance->updated = true;
313 	masks->may_read |= mask;
314 	return 0;
315 }
316 
bpf_mark_stack_read(struct bpf_verifier_env * env,u32 frame,u32 insn_idx,u64 mask)317 int bpf_mark_stack_read(struct bpf_verifier_env *env, u32 frame, u32 insn_idx, u64 mask)
318 {
319 	int err;
320 
321 	err = ensure_cur_instance(env);
322 	err = err ?: mark_stack_read(env, env->liveness->cur_instance, frame, insn_idx, mask);
323 	return err;
324 }
325 
reset_stack_write_marks(struct bpf_verifier_env * env,struct func_instance * instance,u32 insn_idx)326 static void reset_stack_write_marks(struct bpf_verifier_env *env,
327 				    struct func_instance *instance, u32 insn_idx)
328 {
329 	struct bpf_liveness *liveness = env->liveness;
330 	int i;
331 
332 	liveness->write_insn_idx = insn_idx;
333 	for (i = 0; i <= instance->callchain.curframe; i++)
334 		liveness->write_masks_acc[i] = 0;
335 }
336 
bpf_reset_stack_write_marks(struct bpf_verifier_env * env,u32 insn_idx)337 int bpf_reset_stack_write_marks(struct bpf_verifier_env *env, u32 insn_idx)
338 {
339 	struct bpf_liveness *liveness = env->liveness;
340 	int err;
341 
342 	err = ensure_cur_instance(env);
343 	if (err)
344 		return err;
345 
346 	reset_stack_write_marks(env, liveness->cur_instance, insn_idx);
347 	return 0;
348 }
349 
bpf_mark_stack_write(struct bpf_verifier_env * env,u32 frame,u64 mask)350 void bpf_mark_stack_write(struct bpf_verifier_env *env, u32 frame, u64 mask)
351 {
352 	env->liveness->write_masks_acc[frame] |= mask;
353 }
354 
commit_stack_write_marks(struct bpf_verifier_env * env,struct func_instance * instance)355 static int commit_stack_write_marks(struct bpf_verifier_env *env,
356 				    struct func_instance *instance)
357 {
358 	struct bpf_liveness *liveness = env->liveness;
359 	u32 idx, frame, curframe, old_must_write;
360 	struct per_frame_masks *masks;
361 	u64 mask;
362 
363 	if (!instance)
364 		return 0;
365 
366 	curframe = instance->callchain.curframe;
367 	idx = relative_idx(instance, liveness->write_insn_idx);
368 	for (frame = 0; frame <= curframe; frame++) {
369 		mask = liveness->write_masks_acc[frame];
370 		/* avoid allocating frames for zero masks */
371 		if (mask == 0 && !instance->must_write_set[idx])
372 			continue;
373 		masks = alloc_frame_masks(env, instance, frame, liveness->write_insn_idx);
374 		if (IS_ERR(masks))
375 			return PTR_ERR(masks);
376 		old_must_write = masks->must_write;
377 		/*
378 		 * If instruction at this callchain is seen for a first time, set must_write equal
379 		 * to @mask. Otherwise take intersection with the previous value.
380 		 */
381 		if (instance->must_write_set[idx])
382 			mask &= old_must_write;
383 		if (old_must_write != mask) {
384 			masks->must_write = mask;
385 			instance->updated = true;
386 		}
387 		if (old_must_write & ~mask)
388 			instance->must_write_dropped = true;
389 	}
390 	instance->must_write_set[idx] = true;
391 	liveness->write_insn_idx = 0;
392 	return 0;
393 }
394 
395 /*
396  * Merge stack writes marks in @env->liveness->write_masks_acc
397  * with information already in @env->liveness->cur_instance.
398  */
bpf_commit_stack_write_marks(struct bpf_verifier_env * env)399 int bpf_commit_stack_write_marks(struct bpf_verifier_env *env)
400 {
401 	return commit_stack_write_marks(env, env->liveness->cur_instance);
402 }
403 
fmt_callchain(struct bpf_verifier_env * env,struct callchain * callchain)404 static char *fmt_callchain(struct bpf_verifier_env *env, struct callchain *callchain)
405 {
406 	char *buf_end = env->tmp_str_buf + sizeof(env->tmp_str_buf);
407 	char *buf = env->tmp_str_buf;
408 	int i;
409 
410 	buf += snprintf(buf, buf_end - buf, "(");
411 	for (i = 0; i <= callchain->curframe; i++)
412 		buf += snprintf(buf, buf_end - buf, "%s%d", i ? "," : "", callchain->callsites[i]);
413 	snprintf(buf, buf_end - buf, ")");
414 	return env->tmp_str_buf;
415 }
416 
log_mask_change(struct bpf_verifier_env * env,struct callchain * callchain,char * pfx,u32 frame,u32 insn_idx,u64 old,u64 new)417 static void log_mask_change(struct bpf_verifier_env *env, struct callchain *callchain,
418 			    char *pfx, u32 frame, u32 insn_idx, u64 old, u64 new)
419 {
420 	u64 changed_bits = old ^ new;
421 	u64 new_ones = new & changed_bits;
422 	u64 new_zeros = ~new & changed_bits;
423 
424 	if (!changed_bits)
425 		return;
426 	bpf_log(&env->log, "%s frame %d insn %d ", fmt_callchain(env, callchain), frame, insn_idx);
427 	if (new_ones) {
428 		bpf_fmt_stack_mask(env->tmp_str_buf, sizeof(env->tmp_str_buf), new_ones);
429 		bpf_log(&env->log, "+%s %s ", pfx, env->tmp_str_buf);
430 	}
431 	if (new_zeros) {
432 		bpf_fmt_stack_mask(env->tmp_str_buf, sizeof(env->tmp_str_buf), new_zeros);
433 		bpf_log(&env->log, "-%s %s", pfx, env->tmp_str_buf);
434 	}
435 	bpf_log(&env->log, "\n");
436 }
437 
bpf_jmp_offset(struct bpf_insn * insn)438 int bpf_jmp_offset(struct bpf_insn *insn)
439 {
440 	u8 code = insn->code;
441 
442 	if (code == (BPF_JMP32 | BPF_JA))
443 		return insn->imm;
444 	return insn->off;
445 }
446 
447 __diag_push();
448 __diag_ignore_all("-Woverride-init", "Allow field initialization overrides for opcode_info_tbl");
449 
450 /*
451  * Returns an array of instructions succ, with succ->items[0], ...,
452  * succ->items[n-1] with successor instructions, where n=succ->cnt
453  */
454 inline struct bpf_iarray *
bpf_insn_successors(struct bpf_verifier_env * env,u32 idx)455 bpf_insn_successors(struct bpf_verifier_env *env, u32 idx)
456 {
457 	static const struct opcode_info {
458 		bool can_jump;
459 		bool can_fallthrough;
460 	} opcode_info_tbl[256] = {
461 		[0 ... 255] = {.can_jump = false, .can_fallthrough = true},
462 	#define _J(code, ...) \
463 		[BPF_JMP   | code] = __VA_ARGS__, \
464 		[BPF_JMP32 | code] = __VA_ARGS__
465 
466 		_J(BPF_EXIT,  {.can_jump = false, .can_fallthrough = false}),
467 		_J(BPF_JA,    {.can_jump = true,  .can_fallthrough = false}),
468 		_J(BPF_JEQ,   {.can_jump = true,  .can_fallthrough = true}),
469 		_J(BPF_JNE,   {.can_jump = true,  .can_fallthrough = true}),
470 		_J(BPF_JLT,   {.can_jump = true,  .can_fallthrough = true}),
471 		_J(BPF_JLE,   {.can_jump = true,  .can_fallthrough = true}),
472 		_J(BPF_JGT,   {.can_jump = true,  .can_fallthrough = true}),
473 		_J(BPF_JGE,   {.can_jump = true,  .can_fallthrough = true}),
474 		_J(BPF_JSGT,  {.can_jump = true,  .can_fallthrough = true}),
475 		_J(BPF_JSGE,  {.can_jump = true,  .can_fallthrough = true}),
476 		_J(BPF_JSLT,  {.can_jump = true,  .can_fallthrough = true}),
477 		_J(BPF_JSLE,  {.can_jump = true,  .can_fallthrough = true}),
478 		_J(BPF_JCOND, {.can_jump = true,  .can_fallthrough = true}),
479 		_J(BPF_JSET,  {.can_jump = true,  .can_fallthrough = true}),
480 	#undef _J
481 	};
482 	struct bpf_prog *prog = env->prog;
483 	struct bpf_insn *insn = &prog->insnsi[idx];
484 	const struct opcode_info *opcode_info;
485 	struct bpf_iarray *succ, *jt;
486 	int insn_sz;
487 
488 	jt = env->insn_aux_data[idx].jt;
489 	if (unlikely(jt))
490 		return jt;
491 
492 	/* pre-allocated array of size up to 2; reset cnt, as it may have been used already */
493 	succ = env->succ;
494 	succ->cnt = 0;
495 
496 	opcode_info = &opcode_info_tbl[BPF_CLASS(insn->code) | BPF_OP(insn->code)];
497 	insn_sz = bpf_is_ldimm64(insn) ? 2 : 1;
498 	if (opcode_info->can_fallthrough)
499 		succ->items[succ->cnt++] = idx + insn_sz;
500 
501 	if (opcode_info->can_jump)
502 		succ->items[succ->cnt++] = idx + bpf_jmp_offset(insn) + 1;
503 
504 	return succ;
505 }
506 
507 __diag_pop();
508 
get_outer_instance(struct bpf_verifier_env * env,struct func_instance * instance)509 static struct func_instance *get_outer_instance(struct bpf_verifier_env *env,
510 						struct func_instance *instance)
511 {
512 	struct callchain callchain = instance->callchain;
513 
514 	/* Adjust @callchain to represent callchain one frame up */
515 	callchain.callsites[callchain.curframe] = 0;
516 	callchain.sp_starts[callchain.curframe] = 0;
517 	callchain.curframe--;
518 	callchain.callsites[callchain.curframe] = callchain.sp_starts[callchain.curframe];
519 	return __lookup_instance(env, &callchain);
520 }
521 
callchain_subprog_start(struct callchain * callchain)522 static u32 callchain_subprog_start(struct callchain *callchain)
523 {
524 	return callchain->sp_starts[callchain->curframe];
525 }
526 
527 /*
528  * Transfer @may_read and @must_write_acc marks from the first instruction of @instance,
529  * to the call instruction in function instance calling @instance.
530  */
propagate_to_outer_instance(struct bpf_verifier_env * env,struct func_instance * instance)531 static int propagate_to_outer_instance(struct bpf_verifier_env *env,
532 				       struct func_instance *instance)
533 {
534 	struct callchain *callchain = &instance->callchain;
535 	u32 this_subprog_start, callsite, frame;
536 	struct func_instance *outer_instance;
537 	struct per_frame_masks *insn;
538 	int err;
539 
540 	this_subprog_start = callchain_subprog_start(callchain);
541 	outer_instance = get_outer_instance(env, instance);
542 	if (IS_ERR(outer_instance))
543 		return PTR_ERR(outer_instance);
544 	callsite = callchain->callsites[callchain->curframe - 1];
545 
546 	reset_stack_write_marks(env, outer_instance, callsite);
547 	for (frame = 0; frame < callchain->curframe; frame++) {
548 		insn = get_frame_masks(instance, frame, this_subprog_start);
549 		if (!insn)
550 			continue;
551 		bpf_mark_stack_write(env, frame, insn->must_write_acc);
552 		err = mark_stack_read(env, outer_instance, frame, callsite, insn->live_before);
553 		if (err)
554 			return err;
555 	}
556 	commit_stack_write_marks(env, outer_instance);
557 	return 0;
558 }
559 
update_insn(struct bpf_verifier_env * env,struct func_instance * instance,u32 frame,u32 insn_idx)560 static inline bool update_insn(struct bpf_verifier_env *env,
561 			       struct func_instance *instance, u32 frame, u32 insn_idx)
562 {
563 	struct bpf_insn_aux_data *aux = env->insn_aux_data;
564 	u64 new_before, new_after, must_write_acc;
565 	struct per_frame_masks *insn, *succ_insn;
566 	struct bpf_iarray *succ;
567 	u32 s;
568 	bool changed;
569 
570 	succ = bpf_insn_successors(env, insn_idx);
571 	if (succ->cnt == 0)
572 		return false;
573 
574 	changed = false;
575 	insn = get_frame_masks(instance, frame, insn_idx);
576 	new_before = 0;
577 	new_after = 0;
578 	/*
579 	 * New "must_write_acc" is an intersection of all "must_write_acc"
580 	 * of successors plus all "must_write" slots of instruction itself.
581 	 */
582 	must_write_acc = U64_MAX;
583 	for (s = 0; s < succ->cnt; ++s) {
584 		succ_insn = get_frame_masks(instance, frame, succ->items[s]);
585 		new_after |= succ_insn->live_before;
586 		must_write_acc &= succ_insn->must_write_acc;
587 	}
588 	must_write_acc |= insn->must_write;
589 	/*
590 	 * New "live_before" is a union of all "live_before" of successors
591 	 * minus slots written by instruction plus slots read by instruction.
592 	 */
593 	new_before = (new_after & ~insn->must_write) | insn->may_read;
594 	changed |= new_before != insn->live_before;
595 	changed |= must_write_acc != insn->must_write_acc;
596 	if (unlikely(env->log.level & BPF_LOG_LEVEL2) &&
597 	    (insn->may_read || insn->must_write ||
598 	     insn_idx == callchain_subprog_start(&instance->callchain) ||
599 	     aux[insn_idx].prune_point)) {
600 		log_mask_change(env, &instance->callchain, "live",
601 				frame, insn_idx, insn->live_before, new_before);
602 		log_mask_change(env, &instance->callchain, "written",
603 				frame, insn_idx, insn->must_write_acc, must_write_acc);
604 	}
605 	insn->live_before = new_before;
606 	insn->must_write_acc = must_write_acc;
607 	return changed;
608 }
609 
610 /* Fixed-point computation of @live_before and @must_write_acc marks */
update_instance(struct bpf_verifier_env * env,struct func_instance * instance)611 static int update_instance(struct bpf_verifier_env *env, struct func_instance *instance)
612 {
613 	u32 i, frame, po_start, po_end, cnt, this_subprog_start;
614 	struct callchain *callchain = &instance->callchain;
615 	int *insn_postorder = env->cfg.insn_postorder;
616 	struct bpf_subprog_info *subprog;
617 	struct per_frame_masks *insn;
618 	bool changed;
619 	int err;
620 
621 	this_subprog_start = callchain_subprog_start(callchain);
622 	/*
623 	 * If must_write marks were updated must_write_acc needs to be reset
624 	 * (to account for the case when new must_write sets became smaller).
625 	 */
626 	if (instance->must_write_dropped) {
627 		for (frame = 0; frame <= callchain->curframe; frame++) {
628 			if (!instance->frames[frame])
629 				continue;
630 
631 			for (i = 0; i < instance->insn_cnt; i++) {
632 				insn = get_frame_masks(instance, frame, this_subprog_start + i);
633 				insn->must_write_acc = 0;
634 			}
635 		}
636 	}
637 
638 	subprog = bpf_find_containing_subprog(env, this_subprog_start);
639 	po_start = subprog->postorder_start;
640 	po_end = (subprog + 1)->postorder_start;
641 	cnt = 0;
642 	/* repeat until fixed point is reached */
643 	do {
644 		cnt++;
645 		changed = false;
646 		for (frame = 0; frame <= instance->callchain.curframe; frame++) {
647 			if (!instance->frames[frame])
648 				continue;
649 
650 			for (i = po_start; i < po_end; i++)
651 				changed |= update_insn(env, instance, frame, insn_postorder[i]);
652 		}
653 	} while (changed);
654 
655 	if (env->log.level & BPF_LOG_LEVEL2)
656 		bpf_log(&env->log, "%s live stack update done in %d iterations\n",
657 			fmt_callchain(env, callchain), cnt);
658 
659 	/* transfer marks accumulated for outer frames to outer func instance (caller) */
660 	if (callchain->curframe > 0) {
661 		err = propagate_to_outer_instance(env, instance);
662 		if (err)
663 			return err;
664 	}
665 
666 	return 0;
667 }
668 
669 /*
670  * Prepare all callchains within @env->cur_state for querying.
671  * This function should be called after each verifier.c:pop_stack()
672  * and whenever verifier.c:do_check_insn() processes subprogram exit.
673  * This would guarantee that visited verifier states with zero branches
674  * have their bpf_mark_stack_{read,write}() effects propagated in
675  * @env->liveness.
676  */
bpf_update_live_stack(struct bpf_verifier_env * env)677 int bpf_update_live_stack(struct bpf_verifier_env *env)
678 {
679 	struct func_instance *instance;
680 	int err, frame;
681 
682 	bpf_reset_live_stack_callchain(env);
683 	for (frame = env->cur_state->curframe; frame >= 0; --frame) {
684 		instance = lookup_instance(env, env->cur_state, frame);
685 		if (IS_ERR(instance))
686 			return PTR_ERR(instance);
687 
688 		if (instance->updated) {
689 			err = update_instance(env, instance);
690 			if (err)
691 				return err;
692 			instance->updated = false;
693 			instance->must_write_dropped = false;
694 		}
695 	}
696 	return 0;
697 }
698 
is_live_before(struct func_instance * instance,u32 insn_idx,u32 frameno,u32 spi)699 static bool is_live_before(struct func_instance *instance, u32 insn_idx, u32 frameno, u32 spi)
700 {
701 	struct per_frame_masks *masks;
702 
703 	masks = get_frame_masks(instance, frameno, insn_idx);
704 	return masks && (masks->live_before & BIT(spi));
705 }
706 
bpf_live_stack_query_init(struct bpf_verifier_env * env,struct bpf_verifier_state * st)707 int bpf_live_stack_query_init(struct bpf_verifier_env *env, struct bpf_verifier_state *st)
708 {
709 	struct live_stack_query *q = &env->liveness->live_stack_query;
710 	struct func_instance *instance;
711 	u32 frame;
712 
713 	memset(q, 0, sizeof(*q));
714 	for (frame = 0; frame <= st->curframe; frame++) {
715 		instance = lookup_instance(env, st, frame);
716 		if (IS_ERR(instance))
717 			return PTR_ERR(instance);
718 		q->instances[frame] = instance;
719 	}
720 	q->curframe = st->curframe;
721 	q->insn_idx = st->insn_idx;
722 	return 0;
723 }
724 
bpf_stack_slot_alive(struct bpf_verifier_env * env,u32 frameno,u32 spi)725 bool bpf_stack_slot_alive(struct bpf_verifier_env *env, u32 frameno, u32 spi)
726 {
727 	/*
728 	 * Slot is alive if it is read before q->st->insn_idx in current func instance,
729 	 * or if for some outer func instance:
730 	 * - alive before callsite if callsite calls callback, otherwise
731 	 * - alive after callsite
732 	 */
733 	struct live_stack_query *q = &env->liveness->live_stack_query;
734 	struct func_instance *instance, *curframe_instance;
735 	u32 i, callsite;
736 	bool alive;
737 
738 	curframe_instance = q->instances[q->curframe];
739 	if (is_live_before(curframe_instance, q->insn_idx, frameno, spi))
740 		return true;
741 
742 	for (i = frameno; i < q->curframe; i++) {
743 		callsite = curframe_instance->callchain.callsites[i];
744 		instance = q->instances[i];
745 		alive = bpf_calls_callback(env, callsite)
746 			? is_live_before(instance, callsite, frameno, spi)
747 			: is_live_before(instance, callsite + 1, frameno, spi);
748 		if (alive)
749 			return true;
750 	}
751 
752 	return false;
753 }
754