Skip to content

Commit d38ad24

Browse files
peilin-yeAlexei Starovoitov
authored andcommitted
bpf: Factor out check_load_mem() and check_store_reg()
Extract BPF_LDX and most non-ATOMIC BPF_STX instruction handling logic in do_check() into helper functions to be used later. While we are here, make that comment about "reserved fields" more specific. Suggested-by: Eduard Zingerman <[email protected]> Acked-by: Eduard Zingerman <[email protected]> Signed-off-by: Peilin Ye <[email protected]> Link: https://lore.kernel.org/r/8b39c94eac2bb7389ff12392ca666f939124ec4f.1740978603.git.yepeilin@google.com Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent d430c46 commit d38ad24

File tree

1 file changed

+67
-43
lines changed

1 file changed

+67
-43
lines changed

kernel/bpf/verifier.c

Lines changed: 67 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7616,6 +7616,67 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
76167616
static 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, &regs[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+
76197680
static 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, &regs[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

Comments
 (0)