• Oleg Nesterov's avatar
    x86: Introduce TS_COMPAT_RESTART to fix get_nr_restart_syscall() · 8c150ba2
    Oleg Nesterov authored
    The comment in get_nr_restart_syscall() says:
    
    	 * The problem is that we can get here when ptrace pokes
    	 * syscall-like values into regs even if we're not in a syscall
    	 * at all.
    
    Yes, but if not in a syscall then the
    
    	status & (TS_COMPAT|TS_I386_REGS_POKED)
    
    check below can't really help:
    
    	- TS_COMPAT can't be set
    
    	- TS_I386_REGS_POKED is only set if regs->orig_ax was changed by
    	  32bit debugger; and even in this case get_nr_restart_syscall()
    	  is only correct if the tracee is 32bit too.
    
    Suppose that a 64bit debugger plays with a 32bit tracee and
    
    	* Tracee calls sleep(2)	// TS_COMPAT is set
    	* User interrupts the tracee by CTRL-C after 1 sec and does
    	  "(gdb) call func()"
    	* gdb saves the regs by PTRACE_GETREGS
    	* does PTRACE_SETREGS to set %rip='func' and %orig_rax=-1
    	* PTRACE_CONT		// TS_COMPAT is cleared
    	* func() hits int3.
    	* Debugger catches SIGTRAP.
    	* Restore original regs by PTRACE_SETREGS.
    	* PTRACE_CONT
    
    get_nr_restart_syscall() wrongly returns __NR_restart_syscall==219, the
    tracee calls ia32_sys_call_table[219] == sys_madvise.
    
    Add the sticky TS_COMPAT_RESTART flag which survives after return to user
    mode. It's going to be removed in the next step again by storing the
    information in the restart block. As a further cleanup it might be possible
    to remove also TS_I386_REGS_POKED with that.
    
    Test-case:
    
      $ cvs -d :pserver:anoncvs:anoncvs@sourceware.org:/cvs/systemtap co ptrace-tests
      $ gcc -o erestartsys-trap-debuggee ptrace-tests/tests/erestartsys-trap-debuggee.c --m32
      $ gcc -o erestartsys-trap-debugger ptrace-tests/tests/erestartsys-trap-debugger.c -lutil
      $ ./erestartsys-trap-debugger
      Unexpected: retval 1, errno 22
      erestartsys-trap-debugger: ptrace-tests/tests/erestartsys-trap-debugger.c:421
    
    Fixes: 609c19a3 ("x86/ptrace: Stop setting TS_COMPAT in ptrace code")
    Reported-by: default avatarJan Kratochvil <jan.kratochvil@redhat.com>
    Signed-off-by: default avatarOleg Nesterov <oleg@redhat.com>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Cc: stable@vger.kernel.org
    Link: https://lore.kernel.org/r/20210201174709.GA17895@redhat.com
    8c150ba2
signal.c 22.9 KB