|
@@ -202,6 +202,9 @@ struct verifier_env {
|
|
bool allow_ptr_leaks;
|
|
bool allow_ptr_leaks;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+#define BPF_COMPLEXITY_LIMIT_INSNS 65536
|
|
|
|
+#define BPF_COMPLEXITY_LIMIT_STACK 1024
|
|
|
|
+
|
|
/* verbose verifier prints what it's seeing
|
|
/* verbose verifier prints what it's seeing
|
|
* bpf_check() is called under lock, so no race to access these global vars
|
|
* bpf_check() is called under lock, so no race to access these global vars
|
|
*/
|
|
*/
|
|
@@ -454,7 +457,7 @@ static struct verifier_state *push_stack(struct verifier_env *env, int insn_idx,
|
|
elem->next = env->head;
|
|
elem->next = env->head;
|
|
env->head = elem;
|
|
env->head = elem;
|
|
env->stack_size++;
|
|
env->stack_size++;
|
|
- if (env->stack_size > 1024) {
|
|
|
|
|
|
+ if (env->stack_size > BPF_COMPLEXITY_LIMIT_STACK) {
|
|
verbose("BPF program is too complex\n");
|
|
verbose("BPF program is too complex\n");
|
|
goto err;
|
|
goto err;
|
|
}
|
|
}
|
|
@@ -1543,6 +1546,8 @@ peek_stack:
|
|
goto peek_stack;
|
|
goto peek_stack;
|
|
else if (ret < 0)
|
|
else if (ret < 0)
|
|
goto err_free;
|
|
goto err_free;
|
|
|
|
+ if (t + 1 < insn_cnt)
|
|
|
|
+ env->explored_states[t + 1] = STATE_LIST_MARK;
|
|
} else if (opcode == BPF_JA) {
|
|
} else if (opcode == BPF_JA) {
|
|
if (BPF_SRC(insns[t].code) != BPF_K) {
|
|
if (BPF_SRC(insns[t].code) != BPF_K) {
|
|
ret = -EINVAL;
|
|
ret = -EINVAL;
|
|
@@ -1747,7 +1752,7 @@ static int do_check(struct verifier_env *env)
|
|
insn = &insns[insn_idx];
|
|
insn = &insns[insn_idx];
|
|
class = BPF_CLASS(insn->code);
|
|
class = BPF_CLASS(insn->code);
|
|
|
|
|
|
- if (++insn_processed > 32768) {
|
|
|
|
|
|
+ if (++insn_processed > BPF_COMPLEXITY_LIMIT_INSNS) {
|
|
verbose("BPF program is too large. Proccessed %d insn\n",
|
|
verbose("BPF program is too large. Proccessed %d insn\n",
|
|
insn_processed);
|
|
insn_processed);
|
|
return -E2BIG;
|
|
return -E2BIG;
|