Do second pass through CFG and try to evaluate instructions * via each possible path. The verifier will try all paths, tracking types of * registers used as input to instructions, and updating resulting type via * register state values. Plus for each register and possible stack value it * tries to estimate possible max/min value. * For conditional jumps, a stack is used to save evaluation sta
| 2383 | * For now, only states for JCC targets are saved/examined. |
| 2384 | */ |
| 2385 | static int |
| 2386 | evaluate(struct bpf_verifier *bvf) |
| 2387 | { |
| 2388 | int32_t rc; |
| 2389 | uint32_t idx, op; |
| 2390 | const char *err; |
| 2391 | const struct ebpf_insn *ins; |
| 2392 | struct inst_node *next, *node; |
| 2393 | |
| 2394 | struct { |
| 2395 | uint32_t nb_eval; |
| 2396 | uint32_t nb_prune; |
| 2397 | uint32_t nb_save; |
| 2398 | uint32_t nb_restore; |
| 2399 | } stats; |
| 2400 | |
| 2401 | /* initial state of frame pointer */ |
| 2402 | static const struct bpf_reg_val rvfp = { |
| 2403 | .v = { |
| 2404 | .type = BPF_ARG_PTR_STACK, |
| 2405 | .size = MAX_BPF_STACK_SIZE, |
| 2406 | }, |
| 2407 | .mask = UINT64_MAX, |
| 2408 | .u = {.min = MAX_BPF_STACK_SIZE, .max = MAX_BPF_STACK_SIZE}, |
| 2409 | .s = {.min = MAX_BPF_STACK_SIZE, .max = MAX_BPF_STACK_SIZE}, |
| 2410 | }; |
| 2411 | |
| 2412 | bvf->evst->rv[EBPF_REG_1].v = bvf->prm->prog_arg; |
| 2413 | bvf->evst->rv[EBPF_REG_1].mask = UINT64_MAX; |
| 2414 | if (bvf->prm->prog_arg.type == RTE_BPF_ARG_RAW) |
| 2415 | eval_max_bound(bvf->evst->rv + EBPF_REG_1, UINT64_MAX); |
| 2416 | |
| 2417 | bvf->evst->rv[EBPF_REG_10] = rvfp; |
| 2418 | |
| 2419 | ins = bvf->prm->ins; |
| 2420 | node = bvf->in; |
| 2421 | next = node; |
| 2422 | rc = 0; |
| 2423 | |
| 2424 | memset(&stats, 0, sizeof(stats)); |
| 2425 | |
| 2426 | while (node != NULL && rc == 0) { |
| 2427 | |
| 2428 | /* |
| 2429 | * current node evaluation, make sure we evaluate |
| 2430 | * each node only once. |
| 2431 | */ |
| 2432 | if (next != NULL) { |
| 2433 | |
| 2434 | bvf->evin = node; |
| 2435 | idx = get_node_idx(bvf, node); |
| 2436 | op = ins[idx].code; |
| 2437 | |
| 2438 | /* for jcc node make a copy of evaluation state */ |
| 2439 | if (node->nb_edge > 1) { |
| 2440 | rc |= save_cur_eval_state(bvf, node); |
| 2441 | stats.nb_save++; |
| 2442 | } |
no test coverage detected