Skip to content

Commit beaded8

Browse files
iii-ikernel-patches-bot
authored andcommitted
If the original insn is a jump, then it is not subjected to branch
adjustment, which is incorrect. As discovered by Yauheni in https://lore.kernel.org/bpf/[email protected]/ this causes `test_progs -t global_funcs` failures on s390. Most likely, the current code includes the original insn in the patchlet, because there was no infrastructure to insert new insns, only to replace the existing ones. Now that bpf_patch_insns_data() can do insertions, stop including the original insns in zext patchlets. Fixes: a4b1d3c ("bpf: verifier: insert zero extension according to analysis result") Reported-by: Yauheni Kaliuta <[email protected]> Signed-off-by: Ilya Leoshkevich <[email protected]> --- kernel/bpf/verifier.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
1 parent 3a0b5a7 commit beaded8

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

kernel/bpf/verifier.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9911,21 +9911,22 @@ static int opt_remove_nops(struct bpf_verifier_env *env)
99119911
static int opt_subreg_zext_lo32_rnd_hi32(struct bpf_verifier_env *env,
99129912
const union bpf_attr *attr)
99139913
{
9914-
struct bpf_insn *patch, zext_patch[2], rnd_hi32_patch[4];
9914+
struct bpf_insn *patch, zext_patch, rnd_hi32_patch[4];
99159915
struct bpf_insn_aux_data *aux = env->insn_aux_data;
99169916
int i, patch_len, delta = 0, len = env->prog->len;
99179917
struct bpf_insn *insns = env->prog->insnsi;
99189918
struct bpf_prog *new_prog;
99199919
bool rnd_hi32;
99209920

99219921
rnd_hi32 = attr->prog_flags & BPF_F_TEST_RND_HI32;
9922-
zext_patch[1] = BPF_ZEXT_REG(0);
9922+
zext_patch = BPF_ZEXT_REG(0);
99239923
rnd_hi32_patch[1] = BPF_ALU64_IMM(BPF_MOV, BPF_REG_AX, 0);
99249924
rnd_hi32_patch[2] = BPF_ALU64_IMM(BPF_LSH, BPF_REG_AX, 32);
99259925
rnd_hi32_patch[3] = BPF_ALU64_REG(BPF_OR, 0, BPF_REG_AX);
99269926
for (i = 0; i < len; i++) {
99279927
int adj_idx = i + delta;
99289928
struct bpf_insn insn;
9929+
int len_old = 1;
99299930

99309931
insn = insns[adj_idx];
99319932
if (!aux[adj_idx].zext_dst) {
@@ -9968,20 +9969,21 @@ static int opt_subreg_zext_lo32_rnd_hi32(struct bpf_verifier_env *env,
99689969
if (!bpf_jit_needs_zext())
99699970
continue;
99709971

9971-
zext_patch[0] = insn;
9972-
zext_patch[1].dst_reg = insn.dst_reg;
9973-
zext_patch[1].src_reg = insn.dst_reg;
9974-
patch = zext_patch;
9975-
patch_len = 2;
9972+
zext_patch.dst_reg = insn.dst_reg;
9973+
zext_patch.src_reg = insn.dst_reg;
9974+
patch = &zext_patch;
9975+
patch_len = 1;
9976+
adj_idx++;
9977+
len_old = 0;
99769978
apply_patch_buffer:
9977-
new_prog = bpf_patch_insns_data(env, adj_idx, 1, patch,
9979+
new_prog = bpf_patch_insns_data(env, adj_idx, len_old, patch,
99789980
patch_len);
99799981
if (!new_prog)
99809982
return -ENOMEM;
99819983
env->prog = new_prog;
99829984
insns = new_prog->insnsi;
99839985
aux = env->insn_aux_data;
9984-
delta += patch_len - 1;
9986+
delta += patch_len - len_old;
99859987
}
99869988

99879989
return 0;

0 commit comments

Comments
 (0)