|
@@ -1116,7 +1116,12 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
|
|
|
/* ctx accesses must be at a fixed offset, so that we can
|
|
|
* determine what type of data were returned.
|
|
|
*/
|
|
|
- if (!tnum_is_const(reg->var_off)) {
|
|
|
+ if (reg->off) {
|
|
|
+ verbose("dereference of modified ctx ptr R%d off=%d+%d, ctx+const is allowed, ctx+const+const is not\n",
|
|
|
+ regno, reg->off, off - reg->off);
|
|
|
+ return -EACCES;
|
|
|
+ }
|
|
|
+ if (!tnum_is_const(reg->var_off) || reg->var_off.value) {
|
|
|
char tn_buf[48];
|
|
|
|
|
|
tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off);
|
|
@@ -1124,7 +1129,6 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
|
|
|
tn_buf, off, size);
|
|
|
return -EACCES;
|
|
|
}
|
|
|
- off += reg->var_off.value;
|
|
|
err = check_ctx_access(env, insn_idx, off, size, t, ®_type);
|
|
|
if (!err && t == BPF_READ && value_regno >= 0) {
|
|
|
/* ctx access returns either a scalar, or a
|