|
@@ -1172,6 +1172,17 @@ static int check_ld_imm(struct verifier_env *env, struct bpf_insn *insn)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static bool may_access_skb(enum bpf_prog_type type)
|
|
|
|
+{
|
|
|
|
+ switch (type) {
|
|
|
|
+ case BPF_PROG_TYPE_SOCKET_FILTER:
|
|
|
|
+ case BPF_PROG_TYPE_SCHED_CLS:
|
|
|
|
+ return true;
|
|
|
|
+ default:
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
/* verify safety of LD_ABS|LD_IND instructions:
|
|
/* verify safety of LD_ABS|LD_IND instructions:
|
|
* - they can only appear in the programs where ctx == skb
|
|
* - they can only appear in the programs where ctx == skb
|
|
* - since they are wrappers of function calls, they scratch R1-R5 registers,
|
|
* - since they are wrappers of function calls, they scratch R1-R5 registers,
|
|
@@ -1194,8 +1205,8 @@ static int check_ld_abs(struct verifier_env *env, struct bpf_insn *insn)
|
|
struct reg_state *reg;
|
|
struct reg_state *reg;
|
|
int i, err;
|
|
int i, err;
|
|
|
|
|
|
- if (env->prog->aux->prog_type != BPF_PROG_TYPE_SOCKET_FILTER) {
|
|
|
|
- verbose("BPF_LD_ABS|IND instructions are only allowed in socket filters\n");
|
|
|
|
|
|
+ if (!may_access_skb(env->prog->aux->prog_type)) {
|
|
|
|
+ verbose("BPF_LD_ABS|IND instructions not allowed for this program type\n");
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
}
|
|
}
|
|
|
|
|