Commit 4a95c85c authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Alexei Starovoitov

bpf: perform byte-by-byte comparison only when necessary in regsafe()

Extract byte-by-byte comparison of bpf_reg_state in regsafe() into
a helper function, which makes it more convenient to use it "on demand"
only for registers that benefit from such checks, instead of doing it
all the time, even if result of such comparison is ignored.

Also, remove WARN_ON_ONCE(1)+return false dead code. There is no risk of
missing some case as compiler will warn about non-void function not
returning value in some branches (and that under assumption that default
case is removed in the future).
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20221223054921.958283-6-andrii@kernel.orgSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 910f6999
...@@ -13057,18 +13057,19 @@ static void clean_live_states(struct bpf_verifier_env *env, int insn, ...@@ -13057,18 +13057,19 @@ static void clean_live_states(struct bpf_verifier_env *env, int insn,
} }
} }
static bool regs_exact(const struct bpf_reg_state *rold,
const struct bpf_reg_state *rcur)
{
return memcmp(rold, rcur, offsetof(struct bpf_reg_state, parent)) == 0;
}
/* Returns true if (rold safe implies rcur safe) */ /* Returns true if (rold safe implies rcur safe) */
static bool regsafe(struct bpf_verifier_env *env, struct bpf_reg_state *rold, static bool regsafe(struct bpf_verifier_env *env, struct bpf_reg_state *rold,
struct bpf_reg_state *rcur, struct bpf_id_pair *idmap) struct bpf_reg_state *rcur, struct bpf_id_pair *idmap)
{ {
bool equal;
if (!(rold->live & REG_LIVE_READ)) if (!(rold->live & REG_LIVE_READ))
/* explored state didn't use this */ /* explored state didn't use this */
return true; return true;
equal = memcmp(rold, rcur, offsetof(struct bpf_reg_state, parent)) == 0;
if (rold->type == NOT_INIT) if (rold->type == NOT_INIT)
/* explored state can't have used this */ /* explored state can't have used this */
return true; return true;
...@@ -13101,7 +13102,7 @@ static bool regsafe(struct bpf_verifier_env *env, struct bpf_reg_state *rold, ...@@ -13101,7 +13102,7 @@ static bool regsafe(struct bpf_verifier_env *env, struct bpf_reg_state *rold,
switch (base_type(rold->type)) { switch (base_type(rold->type)) {
case SCALAR_VALUE: case SCALAR_VALUE:
if (equal) if (regs_exact(rold, rcur))
return true; return true;
if (env->explore_alu_limits) if (env->explore_alu_limits)
return false; return false;
...@@ -13144,15 +13145,11 @@ static bool regsafe(struct bpf_verifier_env *env, struct bpf_reg_state *rold, ...@@ -13144,15 +13145,11 @@ static bool regsafe(struct bpf_verifier_env *env, struct bpf_reg_state *rold,
/* two stack pointers are equal only if they're pointing to /* two stack pointers are equal only if they're pointing to
* the same stack frame, since fp-8 in foo != fp-8 in bar * the same stack frame, since fp-8 in foo != fp-8 in bar
*/ */
return equal && rold->frameno == rcur->frameno; return regs_exact(rold, rcur) && rold->frameno == rcur->frameno;
default: default:
/* Only valid matches are exact, which memcmp() */ /* Only valid matches are exact, which memcmp() */
return equal; return regs_exact(rold, rcur);
} }
/* Shouldn't get here; if we do, say it's not safe */
WARN_ON_ONCE(1);
return false;
} }
static bool stacksafe(struct bpf_verifier_env *env, struct bpf_func_state *old, static bool stacksafe(struct bpf_verifier_env *env, struct bpf_func_state *old,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment