Skip to content

Commit d430c46

Browse files
peilin-yeAlexei Starovoitov
authored andcommitted
bpf: Factor out check_atomic_rmw()
Currently, check_atomic() only handles atomic read-modify-write (RMW) instructions. Since we are planning to introduce other types of atomic instructions (i.e., atomic load/store), extract the existing RMW handling logic into its own function named check_atomic_rmw(). Remove the @insn_idx parameter as it is not really necessary. Use 'env->insn_idx' instead, as in other places in verifier.c. Signed-off-by: Peilin Ye <[email protected]> Link: https://lore.kernel.org/r/6323ac8e73a10a1c8ee547c77ed68cf8eb6b90e1.1740978603.git.yepeilin@google.com Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent b2d9ef7 commit d430c46

File tree

1 file changed

+29
-24
lines changed

1 file changed

+29
-24
lines changed

kernel/bpf/verifier.c

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7616,28 +7616,12 @@ 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_atomic(struct bpf_verifier_env *env, int insn_idx, struct bpf_insn *insn)
7619+
static int check_atomic_rmw(struct bpf_verifier_env *env,
7620+
struct bpf_insn *insn)
76207621
{
76217622
int load_reg;
76227623
int err;
76237624

7624-
switch (insn->imm) {
7625-
case BPF_ADD:
7626-
case BPF_ADD | BPF_FETCH:
7627-
case BPF_AND:
7628-
case BPF_AND | BPF_FETCH:
7629-
case BPF_OR:
7630-
case BPF_OR | BPF_FETCH:
7631-
case BPF_XOR:
7632-
case BPF_XOR | BPF_FETCH:
7633-
case BPF_XCHG:
7634-
case BPF_CMPXCHG:
7635-
break;
7636-
default:
7637-
verbose(env, "BPF_ATOMIC uses invalid atomic opcode %02x\n", insn->imm);
7638-
return -EINVAL;
7639-
}
7640-
76417625
if (BPF_SIZE(insn->code) != BPF_W && BPF_SIZE(insn->code) != BPF_DW) {
76427626
verbose(env, "invalid atomic operand size\n");
76437627
return -EINVAL;
@@ -7699,12 +7683,12 @@ static int check_atomic(struct bpf_verifier_env *env, int insn_idx, struct bpf_i
76997683
/* Check whether we can read the memory, with second call for fetch
77007684
* case to simulate the register fill.
77017685
*/
7702-
err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
7686+
err = check_mem_access(env, env->insn_idx, insn->dst_reg, insn->off,
77037687
BPF_SIZE(insn->code), BPF_READ, -1, true, false);
77047688
if (!err && load_reg >= 0)
7705-
err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
7706-
BPF_SIZE(insn->code), BPF_READ, load_reg,
7707-
true, false);
7689+
err = check_mem_access(env, env->insn_idx, insn->dst_reg,
7690+
insn->off, BPF_SIZE(insn->code),
7691+
BPF_READ, load_reg, true, false);
77087692
if (err)
77097693
return err;
77107694

@@ -7714,13 +7698,34 @@ static int check_atomic(struct bpf_verifier_env *env, int insn_idx, struct bpf_i
77147698
return err;
77157699
}
77167700
/* Check whether we can write into the same memory. */
7717-
err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
7701+
err = check_mem_access(env, env->insn_idx, insn->dst_reg, insn->off,
77187702
BPF_SIZE(insn->code), BPF_WRITE, -1, true, false);
77197703
if (err)
77207704
return err;
77217705
return 0;
77227706
}
77237707

7708+
static int check_atomic(struct bpf_verifier_env *env, struct bpf_insn *insn)
7709+
{
7710+
switch (insn->imm) {
7711+
case BPF_ADD:
7712+
case BPF_ADD | BPF_FETCH:
7713+
case BPF_AND:
7714+
case BPF_AND | BPF_FETCH:
7715+
case BPF_OR:
7716+
case BPF_OR | BPF_FETCH:
7717+
case BPF_XOR:
7718+
case BPF_XOR | BPF_FETCH:
7719+
case BPF_XCHG:
7720+
case BPF_CMPXCHG:
7721+
return check_atomic_rmw(env, insn);
7722+
default:
7723+
verbose(env, "BPF_ATOMIC uses invalid atomic opcode %02x\n",
7724+
insn->imm);
7725+
return -EINVAL;
7726+
}
7727+
}
7728+
77247729
/* When register 'regno' is used to read the stack (either directly or through
77257730
* a helper function) make sure that it's within stack boundary and, depending
77267731
* on the access type and privileges, that all elements of the stack are
@@ -19224,7 +19229,7 @@ static int do_check(struct bpf_verifier_env *env)
1922419229
enum bpf_reg_type dst_reg_type;
1922519230

1922619231
if (BPF_MODE(insn->code) == BPF_ATOMIC) {
19227-
err = check_atomic(env, env->insn_idx, insn);
19232+
err = check_atomic(env, insn);
1922819233
if (err)
1922919234
return err;
1923019235
env->insn_idx++;

0 commit comments

Comments
 (0)