diff options
| author | Oleg Nesterov <oleg@redhat.com> | 2021-02-01 18:47:09 +0100 | 
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2021-03-16 22:13:11 +0100 | 
| commit | 8c150ba2fb5995c84a7a43848250d444a3329a7d (patch) | |
| tree | 711ea8a4125668f0749c8f0692a258585dec00a0 /include/linux/fpga/fpga-bridge.h | |
| parent | 66c1b6d74cd7035e85c426f0af4aede19e805c8a (diff) | |
x86: Introduce TS_COMPAT_RESTART to fix get_nr_restart_syscall()
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: 609c19a385c8 ("x86/ptrace: Stop setting TS_COMPAT in ptrace code")
Reported-by: Jan Kratochvil <jan.kratochvil@redhat.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20210201174709.GA17895@redhat.com
Diffstat (limited to 'include/linux/fpga/fpga-bridge.h')
0 files changed, 0 insertions, 0 deletions
