@@ -6195,6 +6195,26 @@ static bool is_arena_reg(struct bpf_verifier_env *env, int regno)
6195
6195
return reg->type == PTR_TO_ARENA;
6196
6196
}
6197
6197
6198
+ /* Return false if @regno contains a pointer whose type isn't supported for
6199
+ * atomic instruction @insn.
6200
+ */
6201
+ static bool atomic_ptr_type_ok(struct bpf_verifier_env *env, int regno,
6202
+ struct bpf_insn *insn)
6203
+ {
6204
+ if (is_ctx_reg(env, regno))
6205
+ return false;
6206
+ if (is_pkt_reg(env, regno))
6207
+ return false;
6208
+ if (is_flow_key_reg(env, regno))
6209
+ return false;
6210
+ if (is_sk_reg(env, regno))
6211
+ return false;
6212
+ if (is_arena_reg(env, regno))
6213
+ return bpf_jit_supports_insn(insn, true);
6214
+
6215
+ return true;
6216
+ }
6217
+
6198
6218
static u32 *reg2btf_ids[__BPF_REG_TYPE_MAX] = {
6199
6219
#ifdef CONFIG_NET
6200
6220
[PTR_TO_SOCKET] = &btf_sock_ids[BTF_SOCK_TYPE_SOCK],
@@ -7652,11 +7672,7 @@ static int check_atomic(struct bpf_verifier_env *env, int insn_idx, struct bpf_i
7652
7672
return -EACCES;
7653
7673
}
7654
7674
7655
- if (is_ctx_reg(env, insn->dst_reg) ||
7656
- is_pkt_reg(env, insn->dst_reg) ||
7657
- is_flow_key_reg(env, insn->dst_reg) ||
7658
- is_sk_reg(env, insn->dst_reg) ||
7659
- (is_arena_reg(env, insn->dst_reg) && !bpf_jit_supports_insn(insn, true))) {
7675
+ if (!atomic_ptr_type_ok(env, insn->dst_reg, insn)) {
7660
7676
verbose(env, "BPF_ATOMIC stores into R%d %s is not allowed\n",
7661
7677
insn->dst_reg,
7662
7678
reg_type_str(env, reg_state(env, insn->dst_reg)->type));
0 commit comments