aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/bpf/verifier.c8
-rw-r--r--tools/testing/selftests/bpf/test_verifier.c14
2 files changed, 20 insertions, 2 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 8b8d6ba39e23..20f3889c006e 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1116,7 +1116,12 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
1116 /* ctx accesses must be at a fixed offset, so that we can 1116 /* ctx accesses must be at a fixed offset, so that we can
1117 * determine what type of data were returned. 1117 * determine what type of data were returned.
1118 */ 1118 */
1119 if (!tnum_is_const(reg->var_off)) { 1119 if (reg->off) {
1120 verbose("dereference of modified ctx ptr R%d off=%d+%d, ctx+const is allowed, ctx+const+const is not\n",
1121 regno, reg->off, off - reg->off);
1122 return -EACCES;
1123 }
1124 if (!tnum_is_const(reg->var_off) || reg->var_off.value) {
1120 char tn_buf[48]; 1125 char tn_buf[48];
1121 1126
1122 tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off); 1127 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
1124 tn_buf, off, size); 1129 tn_buf, off, size);
1125 return -EACCES; 1130 return -EACCES;
1126 } 1131 }
1127 off += reg->var_off.value;
1128 err = check_ctx_access(env, insn_idx, off, size, t, &reg_type); 1132 err = check_ctx_access(env, insn_idx, off, size, t, &reg_type);
1129 if (!err && t == BPF_READ && value_regno >= 0) { 1133 if (!err && t == BPF_READ && value_regno >= 0) {
1130 /* ctx access returns either a scalar, or a 1134 /* ctx access returns either a scalar, or a
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
index 26f3250bdcd2..3c7d3a45a3c5 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -6645,6 +6645,20 @@ static struct bpf_test tests[] = {
6645 .errstr = "BPF_END uses reserved fields", 6645 .errstr = "BPF_END uses reserved fields",
6646 .result = REJECT, 6646 .result = REJECT,
6647 }, 6647 },
6648 {
6649 "arithmetic ops make PTR_TO_CTX unusable",
6650 .insns = {
6651 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
6652 offsetof(struct __sk_buff, data) -
6653 offsetof(struct __sk_buff, mark)),
6654 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
6655 offsetof(struct __sk_buff, mark)),
6656 BPF_EXIT_INSN(),
6657 },
6658 .errstr = "dereference of modified ctx ptr R1 off=68+8, ctx+const is allowed, ctx+const+const is not",
6659 .result = REJECT,
6660 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
6661 },
6648}; 6662};
6649 6663
6650static int probe_filter_length(const struct bpf_insn *fp) 6664static int probe_filter_length(const struct bpf_insn *fp)