@@ -7616,6 +7616,67 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
7616
7616
static int save_aux_ptr_type(struct bpf_verifier_env *env, enum bpf_reg_type type,
7617
7617
bool allow_trust_mismatch);
7618
7618
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
+
7619
7680
static int check_atomic_rmw(struct bpf_verifier_env *env,
7620
7681
struct bpf_insn *insn)
7621
7682
{
@@ -19199,35 +19260,16 @@ static int do_check(struct bpf_verifier_env *env)
19199
19260
return err;
19200
19261
19201
19262
} 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;
19210
19264
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().
19219
19267
*/
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");
19226
19270
if (err)
19227
19271
return err;
19228
19272
} else if (class == BPF_STX) {
19229
- enum bpf_reg_type dst_reg_type;
19230
-
19231
19273
if (BPF_MODE(insn->code) == BPF_ATOMIC) {
19232
19274
err = check_atomic(env, insn);
19233
19275
if (err)
@@ -19241,25 +19283,7 @@ static int do_check(struct bpf_verifier_env *env)
19241
19283
return -EINVAL;
19242
19284
}
19243
19285
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);
19263
19287
if (err)
19264
19288
return err;
19265
19289
} else if (class == BPF_ST) {
0 commit comments