@@ -7616,6 +7616,67 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
76167616static int save_aux_ptr_type(struct bpf_verifier_env *env, enum bpf_reg_type type,
76177617 bool allow_trust_mismatch);
76187618
7619+ static int check_load_mem(struct bpf_verifier_env *env, struct bpf_insn *insn,
7620+ bool strict_alignment_once, bool is_ldsx,
7621+ bool allow_trust_mismatch, const char *ctx)
7622+ {
7623+ struct bpf_reg_state *regs = cur_regs(env);
7624+ enum bpf_reg_type src_reg_type;
7625+ int err;
7626+
7627+ /* check src operand */
7628+ err = check_reg_arg(env, insn->src_reg, SRC_OP);
7629+ if (err)
7630+ return err;
7631+
7632+ /* check dst operand */
7633+ err = check_reg_arg(env, insn->dst_reg, DST_OP_NO_MARK);
7634+ if (err)
7635+ return err;
7636+
7637+ src_reg_type = regs[insn->src_reg].type;
7638+
7639+ /* Check if (src_reg + off) is readable. The state of dst_reg will be
7640+ * updated by this call.
7641+ */
7642+ err = check_mem_access(env, env->insn_idx, insn->src_reg, insn->off,
7643+ BPF_SIZE(insn->code), BPF_READ, insn->dst_reg,
7644+ strict_alignment_once, is_ldsx);
7645+ err = err ?: save_aux_ptr_type(env, src_reg_type,
7646+ allow_trust_mismatch);
7647+ err = err ?: reg_bounds_sanity_check(env, ®s[insn->dst_reg], ctx);
7648+
7649+ return err;
7650+ }
7651+
7652+ static int check_store_reg(struct bpf_verifier_env *env, struct bpf_insn *insn,
7653+ bool strict_alignment_once)
7654+ {
7655+ struct bpf_reg_state *regs = cur_regs(env);
7656+ enum bpf_reg_type dst_reg_type;
7657+ int err;
7658+
7659+ /* check src1 operand */
7660+ err = check_reg_arg(env, insn->src_reg, SRC_OP);
7661+ if (err)
7662+ return err;
7663+
7664+ /* check src2 operand */
7665+ err = check_reg_arg(env, insn->dst_reg, SRC_OP);
7666+ if (err)
7667+ return err;
7668+
7669+ dst_reg_type = regs[insn->dst_reg].type;
7670+
7671+ /* Check if (dst_reg + off) is writeable. */
7672+ err = check_mem_access(env, env->insn_idx, insn->dst_reg, insn->off,
7673+ BPF_SIZE(insn->code), BPF_WRITE, insn->src_reg,
7674+ strict_alignment_once, false);
7675+ err = err ?: save_aux_ptr_type(env, dst_reg_type, false);
7676+
7677+ return err;
7678+ }
7679+
76197680static int check_atomic_rmw(struct bpf_verifier_env *env,
76207681 struct bpf_insn *insn)
76217682{
@@ -19186,35 +19247,16 @@ static int do_check(struct bpf_verifier_env *env)
1918619247 return err;
1918719248
1918819249 } else if (class == BPF_LDX) {
19189- enum bpf_reg_type src_reg_type;
19190-
19191- /* check for reserved fields is already done */
19192-
19193- /* check src operand */
19194- err = check_reg_arg(env, insn->src_reg, SRC_OP);
19195- if (err)
19196- return err;
19250+ bool is_ldsx = BPF_MODE(insn->code) == BPF_MEMSX;
1919719251
19198- err = check_reg_arg(env, insn->dst_reg, DST_OP_NO_MARK);
19199- if (err)
19200- return err;
19201-
19202- src_reg_type = regs[insn->src_reg].type;
19203-
19204- /* check that memory (src_reg + off) is readable,
19205- * the state of dst_reg will be updated by this func
19252+ /* Check for reserved fields is already done in
19253+ * resolve_pseudo_ldimm64().
1920619254 */
19207- err = check_mem_access(env, env->insn_idx, insn->src_reg,
19208- insn->off, BPF_SIZE(insn->code),
19209- BPF_READ, insn->dst_reg, false,
19210- BPF_MODE(insn->code) == BPF_MEMSX);
19211- err = err ?: save_aux_ptr_type(env, src_reg_type, true);
19212- err = err ?: reg_bounds_sanity_check(env, ®s[insn->dst_reg], "ldx");
19255+ err = check_load_mem(env, insn, false, is_ldsx, true,
19256+ "ldx");
1921319257 if (err)
1921419258 return err;
1921519259 } else if (class == BPF_STX) {
19216- enum bpf_reg_type dst_reg_type;
19217-
1921819260 if (BPF_MODE(insn->code) == BPF_ATOMIC) {
1921919261 err = check_atomic(env, insn);
1922019262 if (err)
@@ -19228,25 +19270,7 @@ static int do_check(struct bpf_verifier_env *env)
1922819270 return -EINVAL;
1922919271 }
1923019272
19231- /* check src1 operand */
19232- err = check_reg_arg(env, insn->src_reg, SRC_OP);
19233- if (err)
19234- return err;
19235- /* check src2 operand */
19236- err = check_reg_arg(env, insn->dst_reg, SRC_OP);
19237- if (err)
19238- return err;
19239-
19240- dst_reg_type = regs[insn->dst_reg].type;
19241-
19242- /* check that memory (dst_reg + off) is writeable */
19243- err = check_mem_access(env, env->insn_idx, insn->dst_reg,
19244- insn->off, BPF_SIZE(insn->code),
19245- BPF_WRITE, insn->src_reg, false, false);
19246- if (err)
19247- return err;
19248-
19249- err = save_aux_ptr_type(env, dst_reg_type, false);
19273+ err = check_store_reg(env, insn, false);
1925019274 if (err)
1925119275 return err;
1925219276 } else if (class == BPF_ST) {
0 commit comments