bpf_patch_insn_data() replaces one instruction by one in place, and only sets non_stack_access of its aux data from whether the new instruction accesses memory. bpf_patch_list_add() queues such a patch like any other, although it moves nothing, and the commit fills in its aux data the way it does for a longer patch, which keeps non_stack_access of the old instruction where bpf_patch_insn_data() recomputes it. Write a patch of a single instruction to the program right away and adjust its aux data with adjust_insn_aux_data(), as bpf_patch_insn_data() does. Signed-off-by: Qiliang Yuan --- kernel/bpf/fixups.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/fixups.c b/kernel/bpf/fixups.c index 0697f66b1ffc1..a0dd582312d86 100644 --- a/kernel/bpf/fixups.c +++ b/kernel/bpf/fixups.c @@ -382,7 +382,8 @@ struct bpf_prog *bpf_patch_insn_data(struct bpf_verifier_env *env, u32 off, /* * Queue the replacement of insn 'off' by 'patch[0..len)' until - * bpf_patch_list_commit(), see __bpf_patch_list_add(). + * bpf_patch_list_commit(), see __bpf_patch_list_add(). Replacing one insn by + * one moves nothing and is done right away. */ struct bpf_insn *bpf_patch_list_add(struct bpf_verifier_env *env, u32 off, const struct bpf_insn *patch, u32 len) @@ -397,6 +398,13 @@ struct bpf_insn *bpf_patch_list_add(struct bpf_verifier_env *env, u32 off, env, "insn %u patched out of order", off)) return ERR_PTR(-EFAULT); + if (len == 1) { + env->prog->insnsi[off] = *patch; + adjust_insn_aux_data(env, env->prog, off, 1, NULL, + BPF_PATCH_KEEP_TARGET); + return &env->prog->insnsi[off]; + } + return __bpf_patch_list_add(pl, env->prog, off, patch, len); } -- 2.43.0