|
@@ -978,6 +978,13 @@ static bool is_pointer_value(struct bpf_verifier_env *env, int regno)
|
|
return __is_pointer_value(env->allow_ptr_leaks, cur_regs(env) + regno);
|
|
return __is_pointer_value(env->allow_ptr_leaks, cur_regs(env) + regno);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static bool is_ctx_reg(struct bpf_verifier_env *env, int regno)
|
|
|
|
+{
|
|
|
|
+ const struct bpf_reg_state *reg = cur_regs(env) + regno;
|
|
|
|
+
|
|
|
|
+ return reg->type == PTR_TO_CTX;
|
|
|
|
+}
|
|
|
|
+
|
|
static int check_pkt_ptr_alignment(struct bpf_verifier_env *env,
|
|
static int check_pkt_ptr_alignment(struct bpf_verifier_env *env,
|
|
const struct bpf_reg_state *reg,
|
|
const struct bpf_reg_state *reg,
|
|
int off, int size, bool strict)
|
|
int off, int size, bool strict)
|
|
@@ -1258,6 +1265,12 @@ static int check_xadd(struct bpf_verifier_env *env, int insn_idx, struct bpf_ins
|
|
return -EACCES;
|
|
return -EACCES;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (is_ctx_reg(env, insn->dst_reg)) {
|
|
|
|
+ verbose(env, "BPF_XADD stores into R%d context is not allowed\n",
|
|
|
|
+ insn->dst_reg);
|
|
|
|
+ return -EACCES;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* check whether atomic_add can read the memory */
|
|
/* check whether atomic_add can read the memory */
|
|
err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
|
|
err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
|
|
BPF_SIZE(insn->code), BPF_READ, -1);
|
|
BPF_SIZE(insn->code), BPF_READ, -1);
|
|
@@ -3993,6 +4006,12 @@ static int do_check(struct bpf_verifier_env *env)
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
|
|
|
|
|
|
+ if (is_ctx_reg(env, insn->dst_reg)) {
|
|
|
|
+ verbose(env, "BPF_ST stores into R%d context is not allowed\n",
|
|
|
|
+ insn->dst_reg);
|
|
|
|
+ return -EACCES;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* check that memory (dst_reg + off) is writeable */
|
|
/* check that memory (dst_reg + off) is writeable */
|
|
err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
|
|
err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
|
|
BPF_SIZE(insn->code), BPF_WRITE,
|
|
BPF_SIZE(insn->code), BPF_WRITE,
|