Merge tag 'iommu-updates-v4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/joro...
[cascardo/linux.git] / kernel / bpf / verifier.c
index c22ebd3..47dcd3a 100644 (file)
@@ -773,6 +773,8 @@ static int check_func_arg(struct verifier_env *env, u32 regno,
                expected_type = CONST_IMM;
        } else if (arg_type == ARG_CONST_MAP_PTR) {
                expected_type = CONST_PTR_TO_MAP;
+       } else if (arg_type == ARG_PTR_TO_CTX) {
+               expected_type = PTR_TO_CTX;
        } else {
                verbose("unsupported arg_type %d\n", arg_type);
                return -EFAULT;
@@ -1180,6 +1182,7 @@ static bool may_access_skb(enum bpf_prog_type type)
        switch (type) {
        case BPF_PROG_TYPE_SOCKET_FILTER:
        case BPF_PROG_TYPE_SCHED_CLS:
+       case BPF_PROG_TYPE_SCHED_ACT:
                return true;
        default:
                return false;
@@ -1394,7 +1397,8 @@ peek_stack:
                        /* tell verifier to check for equivalent states
                         * after every call and jump
                         */
-                       env->explored_states[t + 1] = STATE_LIST_MARK;
+                       if (t + 1 < insn_cnt)
+                               env->explored_states[t + 1] = STATE_LIST_MARK;
                } else {
                        /* conditional jump with two edges */
                        ret = push_insn(t, t + 1, FALLTHROUGH, env);
@@ -1633,6 +1637,8 @@ static int do_check(struct verifier_env *env)
                        if (err)
                                return err;
 
+                       src_reg_type = regs[insn->src_reg].type;
+
                        /* check that memory (src_reg + off) is readable,
                         * the state of dst_reg will be updated by this func
                         */
@@ -1642,9 +1648,12 @@ static int do_check(struct verifier_env *env)
                        if (err)
                                return err;
 
-                       src_reg_type = regs[insn->src_reg].type;
+                       if (BPF_SIZE(insn->code) != BPF_W) {
+                               insn_idx++;
+                               continue;
+                       }
 
-                       if (insn->imm == 0 && BPF_SIZE(insn->code) == BPF_W) {
+                       if (insn->imm == 0) {
                                /* saw a valid insn
                                 * dst_reg = *(u32 *)(src_reg + off)
                                 * use reserved 'imm' field to mark this insn