On Mon, Jul 14, 2025 at 05:39:15PM +0900, Masami Hiramatsu wrote:

> > +SYSCALL_DEFINE0(uprobe)
> > +{
> > +   struct pt_regs *regs = task_pt_regs(current);
> > +   unsigned long ip, sp, ax_r11_cx_ip[4];
> > +   int err;
> > +
> > +   /* Allow execution only from uprobe trampolines. */
> > +   if (!in_uprobe_trampoline(regs->ip))
> > +           goto sigill;
> > +
> 
> /*
>  * When syscall from the trampoline, including a call to the trampoline
>  * the stack will be shown as;
>  *  regs->sp[0]: [rax]
>  *          [1]: [r11]
>  *          [2]: [rcx]
>  *          [3]: [return-address] (probed address + sizeof(call-instruction))
>  *
>  * And the `&regs->sp[4]` should be the `sp` value when probe is hit.
>  */
> 
> > +   err = copy_from_user(ax_r11_cx_ip, (void __user *)regs->sp, 
> > sizeof(ax_r11_cx_ip));
> > +   if (err)
> > +           goto sigill;
> > +
> > +   ip = regs->ip;
> > +
> > +   /*
> > +    * expose the "right" values of ax/r11/cx/ip/sp to uprobe_consumer/s, 
> > plus:
> > +    * - adjust ip to the probe address, call saved next instruction address
> > +    * - adjust sp to the probe's stack frame (check trampoline code)
> > +    */
> > +   regs->ax  = ax_r11_cx_ip[0];
> > +   regs->r11 = ax_r11_cx_ip[1];
> > +   regs->cx  = ax_r11_cx_ip[2];
> > +   regs->ip  = ax_r11_cx_ip[3] - 5;
> > +   regs->sp += sizeof(ax_r11_cx_ip);
> > +   regs->orig_ax = -1;
> > +

Would not a structure be more natural?

/*
 * See uprobe syscall trampoline; the call to the trampoline will push
 * the return address on the stack, the trampoline itself then pushes
 * cx, r11 and ax.
 */
struct uprobe_syscall_args {
        unsigned long ax;
        unsigned long r11;
        unsigned long cx;
        unsigned long retaddr;
};

        err = copy_from_user(sys_args, (void __user *)regs->sp, 
sizeof(sys_args));
        if (err)
                goto sigill;

        ip = regs->ip;

        regs->ax  = sys_args->ax;
        regs->r11 = sys_args->r11;
        regs->cx  = sys_args->cx;
        regs->ip  = sys_args->retaddr - CALL_INSN_SIZE;
        regs->sp += sizeof(sys_args);

etc.. ?

Reply via email to