@@ -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{
@@ -19199,35 +19260,16 @@ static int do_check(struct bpf_verifier_env *env)
1919919260 return err;
1920019261
1920119262 } else if (class == BPF_LDX) {
19202- enum bpf_reg_type src_reg_type;
19203-
19204- /* check for reserved fields is already done */
19205-
19206- /* check src operand */
19207- err = check_reg_arg(env, insn->src_reg, SRC_OP);
19208- if (err)
19209- return err;
19263+ bool is_ldsx = BPF_MODE(insn->code) == BPF_MEMSX;
1921019264
19211- err = check_reg_arg(env, insn->dst_reg, DST_OP_NO_MARK);
19212- if (err)
19213- return err;
19214-
19215- src_reg_type = regs[insn->src_reg].type;
19216-
19217- /* check that memory (src_reg + off) is readable,
19218- * the state of dst_reg will be updated by this func
19265+ /* Check for reserved fields is already done in
19266+ * resolve_pseudo_ldimm64().
1921919267 */
19220- err = check_mem_access(env, env->insn_idx, insn->src_reg,
19221- insn->off, BPF_SIZE(insn->code),
19222- BPF_READ, insn->dst_reg, false,
19223- BPF_MODE(insn->code) == BPF_MEMSX);
19224- err = err ?: save_aux_ptr_type(env, src_reg_type, true);
19225- err = err ?: reg_bounds_sanity_check(env, ®s[insn->dst_reg], "ldx");
19268+ err = check_load_mem(env, insn, false, is_ldsx, true,
19269+ "ldx");
1922619270 if (err)
1922719271 return err;
1922819272 } else if (class == BPF_STX) {
19229- enum bpf_reg_type dst_reg_type;
19230-
1923119273 if (BPF_MODE(insn->code) == BPF_ATOMIC) {
1923219274 err = check_atomic(env, insn);
1923319275 if (err)
@@ -19241,25 +19283,7 @@ static int do_check(struct bpf_verifier_env *env)
1924119283 return -EINVAL;
1924219284 }
1924319285
19244- /* check src1 operand */
19245- err = check_reg_arg(env, insn->src_reg, SRC_OP);
19246- if (err)
19247- return err;
19248- /* check src2 operand */
19249- err = check_reg_arg(env, insn->dst_reg, SRC_OP);
19250- if (err)
19251- return err;
19252-
19253- dst_reg_type = regs[insn->dst_reg].type;
19254-
19255- /* check that memory (dst_reg + off) is writeable */
19256- err = check_mem_access(env, env->insn_idx, insn->dst_reg,
19257- insn->off, BPF_SIZE(insn->code),
19258- BPF_WRITE, insn->src_reg, false, false);
19259- if (err)
19260- return err;
19261-
19262- err = save_aux_ptr_type(env, dst_reg_type, false);
19286+ err = check_store_reg(env, insn, false);
1926319287 if (err)
1926419288 return err;
1926519289 } else if (class == BPF_ST) {
0 commit comments