diff options
Diffstat (limited to 'kernel/bpf')
| -rw-r--r-- | kernel/bpf/btf.c | 82 | ||||
| -rw-r--r-- | kernel/bpf/core.c | 34 | ||||
| -rw-r--r-- | kernel/bpf/local_storage.c | 3 | ||||
| -rw-r--r-- | kernel/bpf/queue_stack_maps.c | 16 | ||||
| -rw-r--r-- | kernel/bpf/verifier.c | 105 |
5 files changed, 216 insertions, 24 deletions
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index ee4c82667d65..4da543d6bea2 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <uapi/linux/types.h> | 5 | #include <uapi/linux/types.h> |
| 6 | #include <linux/seq_file.h> | 6 | #include <linux/seq_file.h> |
| 7 | #include <linux/compiler.h> | 7 | #include <linux/compiler.h> |
| 8 | #include <linux/ctype.h> | ||
| 8 | #include <linux/errno.h> | 9 | #include <linux/errno.h> |
| 9 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
| 10 | #include <linux/anon_inodes.h> | 11 | #include <linux/anon_inodes.h> |
| @@ -426,6 +427,30 @@ static bool btf_name_offset_valid(const struct btf *btf, u32 offset) | |||
| 426 | offset < btf->hdr.str_len; | 427 | offset < btf->hdr.str_len; |
| 427 | } | 428 | } |
| 428 | 429 | ||
| 430 | /* Only C-style identifier is permitted. This can be relaxed if | ||
| 431 | * necessary. | ||
| 432 | */ | ||
| 433 | static bool btf_name_valid_identifier(const struct btf *btf, u32 offset) | ||
| 434 | { | ||
| 435 | /* offset must be valid */ | ||
| 436 | const char *src = &btf->strings[offset]; | ||
| 437 | const char *src_limit; | ||
| 438 | |||
| 439 | if (!isalpha(*src) && *src != '_') | ||
| 440 | return false; | ||
| 441 | |||
| 442 | /* set a limit on identifier length */ | ||
| 443 | src_limit = src + KSYM_NAME_LEN; | ||
| 444 | src++; | ||
| 445 | while (*src && src < src_limit) { | ||
| 446 | if (!isalnum(*src) && *src != '_') | ||
| 447 | return false; | ||
| 448 | src++; | ||
| 449 | } | ||
| 450 | |||
| 451 | return !*src; | ||
| 452 | } | ||
| 453 | |||
| 429 | static const char *btf_name_by_offset(const struct btf *btf, u32 offset) | 454 | static const char *btf_name_by_offset(const struct btf *btf, u32 offset) |
| 430 | { | 455 | { |
| 431 | if (!offset) | 456 | if (!offset) |
| @@ -1143,6 +1168,22 @@ static int btf_ref_type_check_meta(struct btf_verifier_env *env, | |||
| 1143 | return -EINVAL; | 1168 | return -EINVAL; |
| 1144 | } | 1169 | } |
| 1145 | 1170 | ||
| 1171 | /* typedef type must have a valid name, and other ref types, | ||
| 1172 | * volatile, const, restrict, should have a null name. | ||
| 1173 | */ | ||
| 1174 | if (BTF_INFO_KIND(t->info) == BTF_KIND_TYPEDEF) { | ||
| 1175 | if (!t->name_off || | ||
| 1176 | !btf_name_valid_identifier(env->btf, t->name_off)) { | ||
| 1177 | btf_verifier_log_type(env, t, "Invalid name"); | ||
| 1178 | return -EINVAL; | ||
| 1179 | } | ||
| 1180 | } else { | ||
| 1181 | if (t->name_off) { | ||
| 1182 | btf_verifier_log_type(env, t, "Invalid name"); | ||
| 1183 | return -EINVAL; | ||
| 1184 | } | ||
| 1185 | } | ||
| 1186 | |||
| 1146 | btf_verifier_log_type(env, t, NULL); | 1187 | btf_verifier_log_type(env, t, NULL); |
| 1147 | 1188 | ||
| 1148 | return 0; | 1189 | return 0; |
| @@ -1300,6 +1341,13 @@ static s32 btf_fwd_check_meta(struct btf_verifier_env *env, | |||
| 1300 | return -EINVAL; | 1341 | return -EINVAL; |
| 1301 | } | 1342 | } |
| 1302 | 1343 | ||
| 1344 | /* fwd type must have a valid name */ | ||
| 1345 | if (!t->name_off || | ||
| 1346 | !btf_name_valid_identifier(env->btf, t->name_off)) { | ||
| 1347 | btf_verifier_log_type(env, t, "Invalid name"); | ||
| 1348 | return -EINVAL; | ||
| 1349 | } | ||
| 1350 | |||
| 1303 | btf_verifier_log_type(env, t, NULL); | 1351 | btf_verifier_log_type(env, t, NULL); |
| 1304 | 1352 | ||
| 1305 | return 0; | 1353 | return 0; |
| @@ -1356,6 +1404,12 @@ static s32 btf_array_check_meta(struct btf_verifier_env *env, | |||
| 1356 | return -EINVAL; | 1404 | return -EINVAL; |
| 1357 | } | 1405 | } |
| 1358 | 1406 | ||
| 1407 | /* array type should not have a name */ | ||
| 1408 | if (t->name_off) { | ||
| 1409 | btf_verifier_log_type(env, t, "Invalid name"); | ||
| 1410 | return -EINVAL; | ||
| 1411 | } | ||
| 1412 | |||
| 1359 | if (btf_type_vlen(t)) { | 1413 | if (btf_type_vlen(t)) { |
| 1360 | btf_verifier_log_type(env, t, "vlen != 0"); | 1414 | btf_verifier_log_type(env, t, "vlen != 0"); |
| 1361 | return -EINVAL; | 1415 | return -EINVAL; |
| @@ -1532,6 +1586,13 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env, | |||
| 1532 | return -EINVAL; | 1586 | return -EINVAL; |
| 1533 | } | 1587 | } |
| 1534 | 1588 | ||
| 1589 | /* struct type either no name or a valid one */ | ||
| 1590 | if (t->name_off && | ||
| 1591 | !btf_name_valid_identifier(env->btf, t->name_off)) { | ||
| 1592 | btf_verifier_log_type(env, t, "Invalid name"); | ||
| 1593 | return -EINVAL; | ||
| 1594 | } | ||
| 1595 | |||
| 1535 | btf_verifier_log_type(env, t, NULL); | 1596 | btf_verifier_log_type(env, t, NULL); |
| 1536 | 1597 | ||
| 1537 | last_offset = 0; | 1598 | last_offset = 0; |
| @@ -1543,6 +1604,12 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env, | |||
| 1543 | return -EINVAL; | 1604 | return -EINVAL; |
| 1544 | } | 1605 | } |
| 1545 | 1606 | ||
| 1607 | /* struct member either no name or a valid one */ | ||
| 1608 | if (member->name_off && | ||
| 1609 | !btf_name_valid_identifier(btf, member->name_off)) { | ||
| 1610 | btf_verifier_log_member(env, t, member, "Invalid name"); | ||
| 1611 | return -EINVAL; | ||
| 1612 | } | ||
| 1546 | /* A member cannot be in type void */ | 1613 | /* A member cannot be in type void */ |
| 1547 | if (!member->type || !BTF_TYPE_ID_VALID(member->type)) { | 1614 | if (!member->type || !BTF_TYPE_ID_VALID(member->type)) { |
| 1548 | btf_verifier_log_member(env, t, member, | 1615 | btf_verifier_log_member(env, t, member, |
| @@ -1730,6 +1797,13 @@ static s32 btf_enum_check_meta(struct btf_verifier_env *env, | |||
| 1730 | return -EINVAL; | 1797 | return -EINVAL; |
| 1731 | } | 1798 | } |
| 1732 | 1799 | ||
| 1800 | /* enum type either no name or a valid one */ | ||
| 1801 | if (t->name_off && | ||
| 1802 | !btf_name_valid_identifier(env->btf, t->name_off)) { | ||
| 1803 | btf_verifier_log_type(env, t, "Invalid name"); | ||
| 1804 | return -EINVAL; | ||
| 1805 | } | ||
| 1806 | |||
| 1733 | btf_verifier_log_type(env, t, NULL); | 1807 | btf_verifier_log_type(env, t, NULL); |
| 1734 | 1808 | ||
| 1735 | for (i = 0; i < nr_enums; i++) { | 1809 | for (i = 0; i < nr_enums; i++) { |
| @@ -1739,6 +1813,14 @@ static s32 btf_enum_check_meta(struct btf_verifier_env *env, | |||
| 1739 | return -EINVAL; | 1813 | return -EINVAL; |
| 1740 | } | 1814 | } |
| 1741 | 1815 | ||
| 1816 | /* enum member must have a valid name */ | ||
| 1817 | if (!enums[i].name_off || | ||
| 1818 | !btf_name_valid_identifier(btf, enums[i].name_off)) { | ||
| 1819 | btf_verifier_log_type(env, t, "Invalid name"); | ||
| 1820 | return -EINVAL; | ||
| 1821 | } | ||
| 1822 | |||
| 1823 | |||
| 1742 | btf_verifier_log(env, "\t%s val=%d\n", | 1824 | btf_verifier_log(env, "\t%s val=%d\n", |
| 1743 | btf_name_by_offset(btf, enums[i].name_off), | 1825 | btf_name_by_offset(btf, enums[i].name_off), |
| 1744 | enums[i].val); | 1826 | enums[i].val); |
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 1a796e0799ec..b1a3545d0ec8 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c | |||
| @@ -672,6 +672,40 @@ void __weak bpf_jit_free(struct bpf_prog *fp) | |||
| 672 | bpf_prog_unlock_free(fp); | 672 | bpf_prog_unlock_free(fp); |
| 673 | } | 673 | } |
| 674 | 674 | ||
| 675 | int bpf_jit_get_func_addr(const struct bpf_prog *prog, | ||
| 676 | const struct bpf_insn *insn, bool extra_pass, | ||
| 677 | u64 *func_addr, bool *func_addr_fixed) | ||
| 678 | { | ||
| 679 | s16 off = insn->off; | ||
| 680 | s32 imm = insn->imm; | ||
| 681 | u8 *addr; | ||
| 682 | |||
| 683 | *func_addr_fixed = insn->src_reg != BPF_PSEUDO_CALL; | ||
| 684 | if (!*func_addr_fixed) { | ||
| 685 | /* Place-holder address till the last pass has collected | ||
| 686 | * all addresses for JITed subprograms in which case we | ||
| 687 | * can pick them up from prog->aux. | ||
| 688 | */ | ||
| 689 | if (!extra_pass) | ||
| 690 | addr = NULL; | ||
| 691 | else if (prog->aux->func && | ||
| 692 | off >= 0 && off < prog->aux->func_cnt) | ||
| 693 | addr = (u8 *)prog->aux->func[off]->bpf_func; | ||
| 694 | else | ||
| 695 | return -EINVAL; | ||
| 696 | } else { | ||
| 697 | /* Address of a BPF helper call. Since part of the core | ||
| 698 | * kernel, it's always at a fixed location. __bpf_call_base | ||
| 699 | * and the helper with imm relative to it are both in core | ||
| 700 | * kernel. | ||
| 701 | */ | ||
| 702 | addr = (u8 *)__bpf_call_base + imm; | ||
| 703 | } | ||
| 704 | |||
| 705 | *func_addr = (unsigned long)addr; | ||
| 706 | return 0; | ||
| 707 | } | ||
| 708 | |||
| 675 | static int bpf_jit_blind_insn(const struct bpf_insn *from, | 709 | static int bpf_jit_blind_insn(const struct bpf_insn *from, |
| 676 | const struct bpf_insn *aux, | 710 | const struct bpf_insn *aux, |
| 677 | struct bpf_insn *to_buff) | 711 | struct bpf_insn *to_buff) |
diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c index c97a8f968638..bed9d48a7ae9 100644 --- a/kernel/bpf/local_storage.c +++ b/kernel/bpf/local_storage.c | |||
| @@ -139,7 +139,8 @@ static int cgroup_storage_update_elem(struct bpf_map *map, void *_key, | |||
| 139 | return -ENOENT; | 139 | return -ENOENT; |
| 140 | 140 | ||
| 141 | new = kmalloc_node(sizeof(struct bpf_storage_buffer) + | 141 | new = kmalloc_node(sizeof(struct bpf_storage_buffer) + |
| 142 | map->value_size, __GFP_ZERO | GFP_USER, | 142 | map->value_size, |
| 143 | __GFP_ZERO | GFP_ATOMIC | __GFP_NOWARN, | ||
| 143 | map->numa_node); | 144 | map->numa_node); |
| 144 | if (!new) | 145 | if (!new) |
| 145 | return -ENOMEM; | 146 | return -ENOMEM; |
diff --git a/kernel/bpf/queue_stack_maps.c b/kernel/bpf/queue_stack_maps.c index 8bbd72d3a121..b384ea9f3254 100644 --- a/kernel/bpf/queue_stack_maps.c +++ b/kernel/bpf/queue_stack_maps.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <linux/bpf.h> | 7 | #include <linux/bpf.h> |
| 8 | #include <linux/list.h> | 8 | #include <linux/list.h> |
| 9 | #include <linux/slab.h> | 9 | #include <linux/slab.h> |
| 10 | #include <linux/capability.h> | ||
| 10 | #include "percpu_freelist.h" | 11 | #include "percpu_freelist.h" |
| 11 | 12 | ||
| 12 | #define QUEUE_STACK_CREATE_FLAG_MASK \ | 13 | #define QUEUE_STACK_CREATE_FLAG_MASK \ |
| @@ -45,8 +46,12 @@ static bool queue_stack_map_is_full(struct bpf_queue_stack *qs) | |||
| 45 | /* Called from syscall */ | 46 | /* Called from syscall */ |
| 46 | static int queue_stack_map_alloc_check(union bpf_attr *attr) | 47 | static int queue_stack_map_alloc_check(union bpf_attr *attr) |
| 47 | { | 48 | { |
| 49 | if (!capable(CAP_SYS_ADMIN)) | ||
| 50 | return -EPERM; | ||
| 51 | |||
| 48 | /* check sanity of attributes */ | 52 | /* check sanity of attributes */ |
| 49 | if (attr->max_entries == 0 || attr->key_size != 0 || | 53 | if (attr->max_entries == 0 || attr->key_size != 0 || |
| 54 | attr->value_size == 0 || | ||
| 50 | attr->map_flags & ~QUEUE_STACK_CREATE_FLAG_MASK) | 55 | attr->map_flags & ~QUEUE_STACK_CREATE_FLAG_MASK) |
| 51 | return -EINVAL; | 56 | return -EINVAL; |
| 52 | 57 | ||
| @@ -63,15 +68,10 @@ static struct bpf_map *queue_stack_map_alloc(union bpf_attr *attr) | |||
| 63 | { | 68 | { |
| 64 | int ret, numa_node = bpf_map_attr_numa_node(attr); | 69 | int ret, numa_node = bpf_map_attr_numa_node(attr); |
| 65 | struct bpf_queue_stack *qs; | 70 | struct bpf_queue_stack *qs; |
| 66 | u32 size, value_size; | 71 | u64 size, queue_size, cost; |
| 67 | u64 queue_size, cost; | ||
| 68 | |||
| 69 | size = attr->max_entries + 1; | ||
| 70 | value_size = attr->value_size; | ||
| 71 | |||
| 72 | queue_size = sizeof(*qs) + (u64) value_size * size; | ||
| 73 | 72 | ||
| 74 | cost = queue_size; | 73 | size = (u64) attr->max_entries + 1; |
| 74 | cost = queue_size = sizeof(*qs) + size * attr->value_size; | ||
| 75 | if (cost >= U32_MAX - PAGE_SIZE) | 75 | if (cost >= U32_MAX - PAGE_SIZE) |
| 76 | return ERR_PTR(-E2BIG); | 76 | return ERR_PTR(-E2BIG); |
| 77 | 77 | ||
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 1971ca325fb4..fc760d00a38c 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c | |||
| @@ -175,6 +175,7 @@ struct bpf_verifier_stack_elem { | |||
| 175 | 175 | ||
| 176 | #define BPF_COMPLEXITY_LIMIT_INSNS 131072 | 176 | #define BPF_COMPLEXITY_LIMIT_INSNS 131072 |
| 177 | #define BPF_COMPLEXITY_LIMIT_STACK 1024 | 177 | #define BPF_COMPLEXITY_LIMIT_STACK 1024 |
| 178 | #define BPF_COMPLEXITY_LIMIT_STATES 64 | ||
| 178 | 179 | ||
| 179 | #define BPF_MAP_PTR_UNPRIV 1UL | 180 | #define BPF_MAP_PTR_UNPRIV 1UL |
| 180 | #define BPF_MAP_PTR_POISON ((void *)((0xeB9FUL << 1) + \ | 181 | #define BPF_MAP_PTR_POISON ((void *)((0xeB9FUL << 1) + \ |
| @@ -3751,6 +3752,79 @@ static void find_good_pkt_pointers(struct bpf_verifier_state *vstate, | |||
| 3751 | } | 3752 | } |
| 3752 | } | 3753 | } |
| 3753 | 3754 | ||
| 3755 | /* compute branch direction of the expression "if (reg opcode val) goto target;" | ||
| 3756 | * and return: | ||
| 3757 | * 1 - branch will be taken and "goto target" will be executed | ||
| 3758 | * 0 - branch will not be taken and fall-through to next insn | ||
| 3759 | * -1 - unknown. Example: "if (reg < 5)" is unknown when register value range [0,10] | ||
| 3760 | */ | ||
| 3761 | static int is_branch_taken(struct bpf_reg_state *reg, u64 val, u8 opcode) | ||
| 3762 | { | ||
| 3763 | if (__is_pointer_value(false, reg)) | ||
| 3764 | return -1; | ||
| 3765 | |||
| 3766 | switch (opcode) { | ||
| 3767 | case BPF_JEQ: | ||
| 3768 | if (tnum_is_const(reg->var_off)) | ||
| 3769 | return !!tnum_equals_const(reg->var_off, val); | ||
| 3770 | break; | ||
| 3771 | case BPF_JNE: | ||
| 3772 | if (tnum_is_const(reg->var_off)) | ||
| 3773 | return !tnum_equals_const(reg->var_off, val); | ||
| 3774 | break; | ||
| 3775 | case BPF_JGT: | ||
| 3776 | if (reg->umin_value > val) | ||
| 3777 | return 1; | ||
| 3778 | else if (reg->umax_value <= val) | ||
| 3779 | return 0; | ||
| 3780 | break; | ||
| 3781 | case BPF_JSGT: | ||
| 3782 | if (reg->smin_value > (s64)val) | ||
| 3783 | return 1; | ||
| 3784 | else if (reg->smax_value < (s64)val) | ||
| 3785 | return 0; | ||
| 3786 | break; | ||
| 3787 | case BPF_JLT: | ||
| 3788 | if (reg->umax_value < val) | ||
| 3789 | return 1; | ||
| 3790 | else if (reg->umin_value >= val) | ||
| 3791 | return 0; | ||
| 3792 | break; | ||
| 3793 | case BPF_JSLT: | ||
| 3794 | if (reg->smax_value < (s64)val) | ||
| 3795 | return 1; | ||
| 3796 | else if (reg->smin_value >= (s64)val) | ||
| 3797 | return 0; | ||
| 3798 | break; | ||
| 3799 | case BPF_JGE: | ||
| 3800 | if (reg->umin_value >= val) | ||
| 3801 | return 1; | ||
| 3802 | else if (reg->umax_value < val) | ||
| 3803 | return 0; | ||
| 3804 | break; | ||
| 3805 | case BPF_JSGE: | ||
| 3806 | if (reg->smin_value >= (s64)val) | ||
| 3807 | return 1; | ||
| 3808 | else if (reg->smax_value < (s64)val) | ||
| 3809 | return 0; | ||
| 3810 | break; | ||
| 3811 | case BPF_JLE: | ||
| 3812 | if (reg->umax_value <= val) | ||
| 3813 | return 1; | ||
| 3814 | else if (reg->umin_value > val) | ||
| 3815 | return 0; | ||
| 3816 | break; | ||
| 3817 | case BPF_JSLE: | ||
| 3818 | if (reg->smax_value <= (s64)val) | ||
| 3819 | return 1; | ||
| 3820 | else if (reg->smin_value > (s64)val) | ||
| 3821 | return 0; | ||
| 3822 | break; | ||
| 3823 | } | ||
| 3824 | |||
| 3825 | return -1; | ||
| 3826 | } | ||
| 3827 | |||
| 3754 | /* Adjusts the register min/max values in the case that the dst_reg is the | 3828 | /* Adjusts the register min/max values in the case that the dst_reg is the |
| 3755 | * variable register that we are working on, and src_reg is a constant or we're | 3829 | * variable register that we are working on, and src_reg is a constant or we're |
| 3756 | * simply doing a BPF_K check. | 3830 | * simply doing a BPF_K check. |
| @@ -4152,21 +4226,15 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, | |||
| 4152 | 4226 | ||
| 4153 | dst_reg = ®s[insn->dst_reg]; | 4227 | dst_reg = ®s[insn->dst_reg]; |
| 4154 | 4228 | ||
| 4155 | /* detect if R == 0 where R was initialized to zero earlier */ | 4229 | if (BPF_SRC(insn->code) == BPF_K) { |
| 4156 | if (BPF_SRC(insn->code) == BPF_K && | 4230 | int pred = is_branch_taken(dst_reg, insn->imm, opcode); |
| 4157 | (opcode == BPF_JEQ || opcode == BPF_JNE) && | 4231 | |
| 4158 | dst_reg->type == SCALAR_VALUE && | 4232 | if (pred == 1) { |
| 4159 | tnum_is_const(dst_reg->var_off)) { | 4233 | /* only follow the goto, ignore fall-through */ |
| 4160 | if ((opcode == BPF_JEQ && dst_reg->var_off.value == insn->imm) || | ||
| 4161 | (opcode == BPF_JNE && dst_reg->var_off.value != insn->imm)) { | ||
| 4162 | /* if (imm == imm) goto pc+off; | ||
| 4163 | * only follow the goto, ignore fall-through | ||
| 4164 | */ | ||
| 4165 | *insn_idx += insn->off; | 4234 | *insn_idx += insn->off; |
| 4166 | return 0; | 4235 | return 0; |
| 4167 | } else { | 4236 | } else if (pred == 0) { |
| 4168 | /* if (imm != imm) goto pc+off; | 4237 | /* only follow fall-through branch, since |
| 4169 | * only follow fall-through branch, since | ||
| 4170 | * that's where the program will go | 4238 | * that's where the program will go |
| 4171 | */ | 4239 | */ |
| 4172 | return 0; | 4240 | return 0; |
| @@ -4980,7 +5048,7 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) | |||
| 4980 | struct bpf_verifier_state_list *new_sl; | 5048 | struct bpf_verifier_state_list *new_sl; |
| 4981 | struct bpf_verifier_state_list *sl; | 5049 | struct bpf_verifier_state_list *sl; |
| 4982 | struct bpf_verifier_state *cur = env->cur_state, *new; | 5050 | struct bpf_verifier_state *cur = env->cur_state, *new; |
| 4983 | int i, j, err; | 5051 | int i, j, err, states_cnt = 0; |
| 4984 | 5052 | ||
| 4985 | sl = env->explored_states[insn_idx]; | 5053 | sl = env->explored_states[insn_idx]; |
| 4986 | if (!sl) | 5054 | if (!sl) |
| @@ -5007,8 +5075,12 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) | |||
| 5007 | return 1; | 5075 | return 1; |
| 5008 | } | 5076 | } |
| 5009 | sl = sl->next; | 5077 | sl = sl->next; |
| 5078 | states_cnt++; | ||
| 5010 | } | 5079 | } |
| 5011 | 5080 | ||
| 5081 | if (!env->allow_ptr_leaks && states_cnt > BPF_COMPLEXITY_LIMIT_STATES) | ||
| 5082 | return 0; | ||
| 5083 | |||
| 5012 | /* there were no equivalent states, remember current one. | 5084 | /* there were no equivalent states, remember current one. |
| 5013 | * technically the current state is not proven to be safe yet, | 5085 | * technically the current state is not proven to be safe yet, |
| 5014 | * but it will either reach outer most bpf_exit (which means it's safe) | 5086 | * but it will either reach outer most bpf_exit (which means it's safe) |
| @@ -5148,6 +5220,9 @@ static int do_check(struct bpf_verifier_env *env) | |||
| 5148 | goto process_bpf_exit; | 5220 | goto process_bpf_exit; |
| 5149 | } | 5221 | } |
| 5150 | 5222 | ||
| 5223 | if (signal_pending(current)) | ||
| 5224 | return -EAGAIN; | ||
| 5225 | |||
| 5151 | if (need_resched()) | 5226 | if (need_resched()) |
| 5152 | cond_resched(); | 5227 | cond_resched(); |
| 5153 | 5228 | ||
| @@ -5650,7 +5725,7 @@ static void adjust_subprog_starts(struct bpf_verifier_env *env, u32 off, u32 len | |||
| 5650 | return; | 5725 | return; |
| 5651 | /* NOTE: fake 'exit' subprog should be updated as well. */ | 5726 | /* NOTE: fake 'exit' subprog should be updated as well. */ |
| 5652 | for (i = 0; i <= env->subprog_cnt; i++) { | 5727 | for (i = 0; i <= env->subprog_cnt; i++) { |
| 5653 | if (env->subprog_info[i].start < off) | 5728 | if (env->subprog_info[i].start <= off) |
| 5654 | continue; | 5729 | continue; |
| 5655 | env->subprog_info[i].start += len - 1; | 5730 | env->subprog_info[i].start += len - 1; |
| 5656 | } | 5731 | } |
