Revert "bpf: handle ldimm64 properly in check_cfg()"
This reverts commit b08acd5c46
which is
commit 3feb263bb516ee7e1da0acd22b15afbb9a7daa19 upstream.
It breaks the Android kernel abi and can be brought back in the future
in an abi-safe way if it is really needed.
Bug: 161946584
Change-Id: Ic364d3f09e551f26324d7519bd97f08c9ce30542
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
parent
63ca0ed629
commit
1699079678
@ -708,14 +708,10 @@ bpf_ctx_record_field_size(struct bpf_insn_access_aux *aux, u32 size)
|
||||
aux->ctx_field_size = size;
|
||||
}
|
||||
|
||||
static bool bpf_is_ldimm64(const struct bpf_insn *insn)
|
||||
{
|
||||
return insn->code == (BPF_LD | BPF_IMM | BPF_DW);
|
||||
}
|
||||
|
||||
static inline bool bpf_pseudo_func(const struct bpf_insn *insn)
|
||||
{
|
||||
return bpf_is_ldimm64(insn) && insn->src_reg == BPF_PSEUDO_FUNC;
|
||||
return insn->code == (BPF_LD | BPF_IMM | BPF_DW) &&
|
||||
insn->src_reg == BPF_PSEUDO_FUNC;
|
||||
}
|
||||
|
||||
struct bpf_prog_ops {
|
||||
|
@ -11107,16 +11107,15 @@ static int visit_func_call_insn(int t, struct bpf_insn *insns,
|
||||
struct bpf_verifier_env *env,
|
||||
bool visit_callee)
|
||||
{
|
||||
int ret, insn_sz;
|
||||
int ret;
|
||||
|
||||
insn_sz = bpf_is_ldimm64(&insns[t]) ? 2 : 1;
|
||||
ret = push_insn(t, t + insn_sz, FALLTHROUGH, env, false);
|
||||
ret = push_insn(t, t + 1, FALLTHROUGH, env, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mark_prune_point(env, t + insn_sz);
|
||||
mark_prune_point(env, t + 1);
|
||||
/* when we exit from subprog, we need to record non-linear history */
|
||||
mark_jmp_point(env, t + insn_sz);
|
||||
mark_jmp_point(env, t + 1);
|
||||
|
||||
if (visit_callee) {
|
||||
mark_prune_point(env, t);
|
||||
@ -11138,17 +11137,15 @@ static int visit_func_call_insn(int t, struct bpf_insn *insns,
|
||||
static int visit_insn(int t, struct bpf_verifier_env *env)
|
||||
{
|
||||
struct bpf_insn *insns = env->prog->insnsi, *insn = &insns[t];
|
||||
int ret, off, insn_sz;
|
||||
int ret, off;
|
||||
|
||||
if (bpf_pseudo_func(insn))
|
||||
return visit_func_call_insn(t, insns, env, true);
|
||||
|
||||
/* All non-branch instructions have a single fall-through edge. */
|
||||
if (BPF_CLASS(insn->code) != BPF_JMP &&
|
||||
BPF_CLASS(insn->code) != BPF_JMP32) {
|
||||
insn_sz = bpf_is_ldimm64(insn) ? 2 : 1;
|
||||
return push_insn(t, t + insn_sz, FALLTHROUGH, env, false);
|
||||
}
|
||||
BPF_CLASS(insn->code) != BPF_JMP32)
|
||||
return push_insn(t, t + 1, FALLTHROUGH, env, false);
|
||||
|
||||
switch (BPF_OP(insn->code)) {
|
||||
case BPF_EXIT:
|
||||
@ -11247,21 +11244,11 @@ static int check_cfg(struct bpf_verifier_env *env)
|
||||
}
|
||||
|
||||
for (i = 0; i < insn_cnt; i++) {
|
||||
struct bpf_insn *insn = &env->prog->insnsi[i];
|
||||
|
||||
if (insn_state[i] != EXPLORED) {
|
||||
verbose(env, "unreachable insn %d\n", i);
|
||||
ret = -EINVAL;
|
||||
goto err_free;
|
||||
}
|
||||
if (bpf_is_ldimm64(insn)) {
|
||||
if (insn_state[i + 1] != 0) {
|
||||
verbose(env, "jump into the middle of ldimm64 insn %d\n", i);
|
||||
ret = -EINVAL;
|
||||
goto err_free;
|
||||
}
|
||||
i++; /* skip second half of ldimm64 */
|
||||
}
|
||||
}
|
||||
ret = 0; /* cfg looks good */
|
||||
|
||||
|
@ -9,8 +9,8 @@
|
||||
BPF_MOV64_IMM(BPF_REG_0, 2),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.errstr = "jump into the middle of ldimm64 insn 1",
|
||||
.errstr_unpriv = "jump into the middle of ldimm64 insn 1",
|
||||
.errstr = "invalid BPF_LD_IMM insn",
|
||||
.errstr_unpriv = "R1 pointer comparison",
|
||||
.result = REJECT,
|
||||
},
|
||||
{
|
||||
@ -23,8 +23,8 @@
|
||||
BPF_LD_IMM64(BPF_REG_0, 1),
|
||||
BPF_EXIT_INSN(),
|
||||
},
|
||||
.errstr = "jump into the middle of ldimm64 insn 1",
|
||||
.errstr_unpriv = "jump into the middle of ldimm64 insn 1",
|
||||
.errstr = "invalid BPF_LD_IMM insn",
|
||||
.errstr_unpriv = "R1 pointer comparison",
|
||||
.result = REJECT,
|
||||
},
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user