mirror of
https://github.com/torvalds/linux.git
synced 2026-06-02 19:43:40 +02:00
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 <eddyz87@gmail.com> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Signed-off-by: Peilin Ye <yepeilin@google.com> Link: https://lore.kernel.org/r/8b39c94eac2bb7389ff12392ca666f939124ec4f.1740978603.git.yepeilin@google.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
2626ffe9f3
commit
a752ba4332
|
|
@ -7616,6 +7616,67 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
|
|||
static int save_aux_ptr_type(struct bpf_verifier_env *env, enum bpf_reg_type type,
|
||||
bool allow_trust_mismatch);
|
||||
|
||||
static int check_load_mem(struct bpf_verifier_env *env, struct bpf_insn *insn,
|
||||
bool strict_alignment_once, bool is_ldsx,
|
||||
bool allow_trust_mismatch, const char *ctx)
|
||||
{
|
||||
struct bpf_reg_state *regs = cur_regs(env);
|
||||
enum bpf_reg_type src_reg_type;
|
||||
int err;
|
||||
|
||||
/* check src operand */
|
||||
err = check_reg_arg(env, insn->src_reg, SRC_OP);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* check dst operand */
|
||||
err = check_reg_arg(env, insn->dst_reg, DST_OP_NO_MARK);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
src_reg_type = regs[insn->src_reg].type;
|
||||
|
||||
/* Check if (src_reg + off) is readable. The state of dst_reg will be
|
||||
* updated by this call.
|
||||
*/
|
||||
err = check_mem_access(env, env->insn_idx, insn->src_reg, insn->off,
|
||||
BPF_SIZE(insn->code), BPF_READ, insn->dst_reg,
|
||||
strict_alignment_once, is_ldsx);
|
||||
err = err ?: save_aux_ptr_type(env, src_reg_type,
|
||||
allow_trust_mismatch);
|
||||
err = err ?: reg_bounds_sanity_check(env, ®s[insn->dst_reg], ctx);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int check_store_reg(struct bpf_verifier_env *env, struct bpf_insn *insn,
|
||||
bool strict_alignment_once)
|
||||
{
|
||||
struct bpf_reg_state *regs = cur_regs(env);
|
||||
enum bpf_reg_type dst_reg_type;
|
||||
int err;
|
||||
|
||||
/* check src1 operand */
|
||||
err = check_reg_arg(env, insn->src_reg, SRC_OP);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* check src2 operand */
|
||||
err = check_reg_arg(env, insn->dst_reg, SRC_OP);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dst_reg_type = regs[insn->dst_reg].type;
|
||||
|
||||
/* Check if (dst_reg + off) is writeable. */
|
||||
err = check_mem_access(env, env->insn_idx, insn->dst_reg, insn->off,
|
||||
BPF_SIZE(insn->code), BPF_WRITE, insn->src_reg,
|
||||
strict_alignment_once, false);
|
||||
err = err ?: save_aux_ptr_type(env, dst_reg_type, false);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int check_atomic_rmw(struct bpf_verifier_env *env,
|
||||
struct bpf_insn *insn)
|
||||
{
|
||||
|
|
@ -19199,35 +19260,16 @@ static int do_check(struct bpf_verifier_env *env)
|
|||
return err;
|
||||
|
||||
} else if (class == BPF_LDX) {
|
||||
enum bpf_reg_type src_reg_type;
|
||||
bool is_ldsx = BPF_MODE(insn->code) == BPF_MEMSX;
|
||||
|
||||
/* check for reserved fields is already done */
|
||||
|
||||
/* check src operand */
|
||||
err = check_reg_arg(env, insn->src_reg, SRC_OP);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = check_reg_arg(env, insn->dst_reg, DST_OP_NO_MARK);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
src_reg_type = regs[insn->src_reg].type;
|
||||
|
||||
/* check that memory (src_reg + off) is readable,
|
||||
* the state of dst_reg will be updated by this func
|
||||
/* Check for reserved fields is already done in
|
||||
* resolve_pseudo_ldimm64().
|
||||
*/
|
||||
err = check_mem_access(env, env->insn_idx, insn->src_reg,
|
||||
insn->off, BPF_SIZE(insn->code),
|
||||
BPF_READ, insn->dst_reg, false,
|
||||
BPF_MODE(insn->code) == BPF_MEMSX);
|
||||
err = err ?: save_aux_ptr_type(env, src_reg_type, true);
|
||||
err = err ?: reg_bounds_sanity_check(env, ®s[insn->dst_reg], "ldx");
|
||||
err = check_load_mem(env, insn, false, is_ldsx, true,
|
||||
"ldx");
|
||||
if (err)
|
||||
return err;
|
||||
} else if (class == BPF_STX) {
|
||||
enum bpf_reg_type dst_reg_type;
|
||||
|
||||
if (BPF_MODE(insn->code) == BPF_ATOMIC) {
|
||||
err = check_atomic(env, insn);
|
||||
if (err)
|
||||
|
|
@ -19241,25 +19283,7 @@ static int do_check(struct bpf_verifier_env *env)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* check src1 operand */
|
||||
err = check_reg_arg(env, insn->src_reg, SRC_OP);
|
||||
if (err)
|
||||
return err;
|
||||
/* check src2 operand */
|
||||
err = check_reg_arg(env, insn->dst_reg, SRC_OP);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dst_reg_type = regs[insn->dst_reg].type;
|
||||
|
||||
/* check that memory (dst_reg + off) is writeable */
|
||||
err = check_mem_access(env, env->insn_idx, insn->dst_reg,
|
||||
insn->off, BPF_SIZE(insn->code),
|
||||
BPF_WRITE, insn->src_reg, false, false);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = save_aux_ptr_type(env, dst_reg_type, false);
|
||||
err = check_store_reg(env, insn, false);
|
||||
if (err)
|
||||
return err;
|
||||
} else if (class == BPF_ST) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user