uprobe programs are allowed to modify struct pt_regs. Since the actual program type of uprobe is KPROBE, it can be abused to modify struct pt_regs via kprobe+freplace when the kprobe attaches to kernel functions. For example, SEC("?kprobe") int kprobe(struct pt_regs *regs) { return 0; } SEC("?freplace") int freplace_kprobe(struct pt_regs *regs) { regs->di = 0; return 0; } freplace_kprobe prog will attach to kprobe prog. kprobe prog will attach to a kernel function. Without this patch, when the kernel function runs, its first arg will always be set as 0 via the freplace_kprobe prog. To avoid the abuse of kprobe_write_ctx=true via kprobe+freplace, disallow freplace on kprobe programs with mismatched kprobe_write_ctx values. Fixes: 7384893d970e ("bpf: Allow uprobe program to change context registers") Signed-off-by: Leon Hwang --- kernel/bpf/verifier.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 12330466d58b..f8257bae6081 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -6404,6 +6404,14 @@ static int check_ctx_access(struct bpf_verifier_env *env, int insn_idx, int off, /* remember the offset of last byte accessed in ctx */ if (env->prog->aux->max_ctx_offset < off + size) env->prog->aux->max_ctx_offset = off + size; + if (env->prog->type == BPF_PROG_TYPE_EXT) { + struct bpf_prog *dst_prog = env->prog->aux->dst_prog; + + if (env->prog->aux->kprobe_write_ctx != dst_prog->aux->kprobe_write_ctx) { + verbose(env, "Extension program cannot have different kprobe_write_ctx value with target prog\n"); + return -EINVAL; + } + } return 0; } -- 2.53.0