Since this changes the function's meaning, rename it to bpf_patch_insns(). It is still expected to only grow the function or to preserve its size, not to shrink it. Signed-off-by: Ilya Leoshkevich <iii@xxxxxxxxxxxxx> --- include/linux/filter.h | 4 ++-- kernel/bpf/core.c | 18 +++++++++--------- kernel/bpf/verifier.c | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/linux/filter.h b/include/linux/filter.h index 995625950cc1..d926ab1cfada 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -892,8 +892,8 @@ static inline bool bpf_dump_raw_ok(const struct cred *cred) return kallsyms_show_value(cred); } -struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off, - const struct bpf_insn *patch, u32 len); +struct bpf_prog *bpf_patch_insns(struct bpf_prog *prog, u32 off, u32 len_old, + const struct bpf_insn *patch, u32 len); int bpf_remove_insns(struct bpf_prog *prog, u32 off, u32 cnt); void bpf_clear_redirect_map(struct bpf_map *map); diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index ed0b3578867c..dde5f61f5a99 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -429,10 +429,10 @@ static void bpf_adj_linfo(struct bpf_prog *prog, u32 off, u32 delta) linfo[i].insn_off += delta; } -struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off, - const struct bpf_insn *patch, u32 len) +struct bpf_prog *bpf_patch_insns(struct bpf_prog *prog, u32 off, u32 len_old, + const struct bpf_insn *patch, u32 len) { - u32 insn_adj_cnt, insn_rest, insn_delta = len - 1; + u32 insn_adj_cnt, insn_rest, insn_delta = len - len_old; const u32 cnt_max = S16_MAX; struct bpf_prog *prog_adj; int err; @@ -451,7 +451,7 @@ struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off, * we afterwards may not fail anymore. */ if (insn_adj_cnt > cnt_max && - (err = bpf_adj_branches(prog, off, off + 1, off + len, true))) + (err = bpf_adj_branches(prog, off, off + len_old, off + len, true))) return ERR_PTR(err); /* Several new instructions need to be inserted. Make room @@ -468,14 +468,13 @@ struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off, /* Patching happens in 3 steps: * * 1) Move over tail of insnsi from next instruction onwards, - * so we can patch the single target insn with one or more - * new ones (patching is always from 1 to n insns, n > 0). + * so we can patch the target insns. * 2) Inject new instructions at the target location. * 3) Adjust branch offsets if necessary. */ insn_rest = insn_adj_cnt - off - len; - memmove(prog_adj->insnsi + off + len, prog_adj->insnsi + off + 1, + memmove(prog_adj->insnsi + off + len, prog_adj->insnsi + off + len_old, sizeof(*patch) * insn_rest); memcpy(prog_adj->insnsi + off, patch, sizeof(*patch) * len); @@ -483,7 +482,8 @@ struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off, * the ship has sailed to reverse to the original state. An * overflow cannot happen at this point. */ - BUG_ON(bpf_adj_branches(prog_adj, off, off + 1, off + len, false)); + BUG_ON(bpf_adj_branches(prog_adj, off, off + len_old, off + len, + false)); bpf_adj_linfo(prog_adj, off, insn_delta); @@ -1155,7 +1155,7 @@ struct bpf_prog *bpf_jit_blind_constants(struct bpf_prog *prog) if (!rewritten) continue; - tmp = bpf_patch_insn_single(clone, i, insn_buff, rewritten); + tmp = bpf_patch_insns(clone, i, 1, insn_buff, rewritten); if (IS_ERR(tmp)) { /* Patching may have repointed aux->prog during * realloc from the original one, so we need to diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 814bc6c1ad16..dd0b138ee382 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -9628,7 +9628,7 @@ static struct bpf_prog *bpf_patch_insn_data(struct bpf_verifier_env *env, u32 of { struct bpf_prog *new_prog; - new_prog = bpf_patch_insn_single(env->prog, off, patch, len); + new_prog = bpf_patch_insns(env->prog, off, 1, patch, len); if (IS_ERR(new_prog)) { if (PTR_ERR(new_prog) == -ERANGE) verbose(env, -- 2.25.4