Re: [RFC PATCH 2/2] riscv: selftests: Add a ptrace test to check a0 of restarted syscall

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Jun 21, 2024 at 02:29:07PM +0800, Quan Zhou wrote:
> 
> 
> On 2024/6/20 10:55, Charlie Jenkins wrote:
> > On Wed, Jun 19, 2024 at 10:01:47AM +0800, zhouquan@xxxxxxxxxxx wrote:
> > > From: Quan Zhou <zhouquan@xxxxxxxxxxx>
> > > 
> > > This test creates two processes: a tracer and a tracee. The tracer actively
> > > sends a SIGUSR1 signal in user mode to interrupt the read syscall being
> > > executed by the tracee. We will reset a0/orig_a0 and then observe the value
> > > of a0 held by the restarted read syscall.
> > 
> > I don't quite follow what the goal of this test is. With orig_a0 being
> > added to the previous patch for ptrace, a more constrained test could
> > ensure that this value is respected.
> > 
> 
> Sry, I may not have described the patch clearly enough. This patch provides
> a channel for modifying a0 in user-space ptrace via orig_a0. Here, I will
> try to outline the whole situation:
> 
> 1、When the tracer calls ptrace to modify regs->a0, can the tracee's a0 be
> correctly modified?
> 
> Through testing, if the user only modifies regs->a0, it doesn't work. Why?
> 
> The execution flow of the tracee in the test program is as follows.Prior to
> this explanation:
> 
> - PTRACE_SYSCALL can make the tracee block before and after executing
>   a syscall.
> - The tracer sends SIGUSR1 to interrupt read, and the kernel will
>   restart it.
> - Please note the point marked with (*), which I believe is the cause
>   of the issue.
> 
> user     kernel
>     |
>     |
>     |
>      read
>         | +-> regs->orig_a0 = regs->a0; //(*1)
>         |                                       <=tracer:PTRACE_SYSCALL
>         | +-> syscall_enter_from_user_mode
>               +-> ptrace_report_syscall_entry
>                   +-> ptrace_stop
>         | //stopped
>         |                                       <= tracer:SIGUSR1
>         |
>         | //resume                              <= tracer:PTRACE_SYSCALL
>         | syscall_handler...
>         |
>         | +-> syscall_exit_to_user_mode
>               +-> syscall_exit_to_user_mode_prepare
>                   +-> ptrace_report_syscall_exit
>                       +-> ptrace_stop
>     | //stopped
>     |
>     | /* Change a0/orig_a0 here and observe the restarted syscall */
>     | regs->{a0/orig_a0} = fd_zero; //(*2)
>     | ptrace(PTRACE_SETREGSET, ...);
>         |                                      <= tracer:PTRACE_SYSCALL
>         | //restarting..., skip SIGUSR1
>         |
>         | +-> exit_to_user_mode_loop
>               +-> arch_do_signal_or_restart
>                   +-> /* Settings for syscall restart */
>                       regs->a0 = regs->orig_a0; //(*3)
>     | //stopped
>     | //and block before the syscall again, get current regs->a0
>     | *result = regs->a0;
>     |
>     | /* Now, Check regs->a0 of restarted syscall */
>     | EXPECT_NE(0x5, result); //for PTRACE_SETREGSSET a0, failed
>     | EXPECT_EQ(0x5, result); //for PTRACE_SETREGSSET orig_a0, succeed
> 
> If I'm wrong, please let me know. 🙂
> 
> 2、Actually, I discovered the issue while using the execve function.
> When I tried to modify the first parameter of execve in the tracer,
> I found it didn't work.
> 
> As for why not use execve for testing, there are two reasons:
> 
> 1) The root cause of this issue is that when a syscall is interrupted
> and then resumed, it restarts with orig_a0 instead of a0, so modifying
> a0 doesn't work. I want to focus the test on the "restarted syscall".
> 
> 2) Compared to the current test scenario, execve is terminated by ptrace
> earlier, so I chose a later point. In fact, setting regs->a0 in the path
> between (*1) and (*3) is ineffective because it will eventually be
> overwritten by orig_a0, correct?

Thank you for the thorough explanation! I feel like a test case like the
following achieves the same goal but without needing the pipes and the
file. What do you think?


[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux