linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] x86/ptrace: Remove questionable TS_COMPAT usage in ptrace
@ 2016-06-18 10:21 Andy Lutomirski
  2016-06-18 13:55 ` Pedro Alves
                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Andy Lutomirski @ 2016-06-18 10:21 UTC (permalink / raw)
  To: x86
  Cc: linux-kernel, Kees Cook, Borislav Petkov, Oleg Nesterov, Andy Lutomirski

A 32-bit tracer can set a tracee's TS_COMPAT flag by poking orig_ax.

- If the tracee is stopped in a 32-bit syscall, this has no effect
  as TS_COMPAT will already be set.

- If the tracee is stopped on entry to a 64-bit syscall, this could
  cause problems: in_compat_syscall() etc will be out of sync with
  the actual syscall table in use.  I can imagine this bre aking
  audit.  (It can't meaningfully break seccomp, as a malicious
  tracer can already fully bypass seccomp.)  I could also imagine it
  subtly confusing the implementations of a few syscalls.

 - If the tracee is stopped in a non-syscall context, then TS_COMPAT
   will end up set in user mode, which isn't supposed to happen.  The results
   are likely to be similar to the 64-bit syscall entry case.

Fix it by deleting the code.

Here's my understanding of the previous intent.  Suppose a
32-bit tracee makes a syscall that returns one of the -ERESTART
codes.  A 32-bit tracer saves away its register state.  The tracee
resumes, returns from the system call, and gets stopped again for a
non-syscall reason (e.g. a signal).  Then the tracer tries to roll
back the tracee's state by writing all of the saved registers back.

The result of this sequence of events will be that the tracee's
registers' low bits match what they were at the end of the syscall
but TS_COMPAT will be clear.  This will cause syscall_get_error() to
return a *positive* number, because we zero-extend registers poked
by 32-bit tracers instead of sign-extending them.  As a result, with
this change, syscall restart won't happen, whereas, historically, it
would have happened.

As far as I can tell, this corner case isn't very important, and I
also don't see how one would reasonably have triggered it in the
first place.  In particular, syscall restart happens before ptrace
hooks in the syscall exit path, so a tracer should never see the
problematic pre-restart syscall state in the first place.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
---

Oleg, you often have good insight into ptrace oddities.  Do you think I'm
correct that this can safely be deleted?

Kees, I think that either this or a similar fix is important to make the
seccomp reordering series be fully effective.

Ingo, this is intended for x86/urgent.  I deliberately didn't cc stable,
as the bug this fixes seems minor enough that I think we can wait a while
to backport it.

arch/x86/kernel/ptrace.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 600edd225e81..bde57caf9aa9 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -922,16 +922,7 @@ static int putreg32(struct task_struct *child, unsigned regno, u32 value)
 	R32(esp, sp);
 
 	case offsetof(struct user32, regs.orig_eax):
-		/*
-		 * A 32-bit debugger setting orig_eax means to restore
-		 * the state of the task restarting a 32-bit syscall.
-		 * Make sure we interpret the -ERESTART* codes correctly
-		 * in case the task is not actually still sitting at the
-		 * exit from a 32-bit syscall with TS_COMPAT still set.
-		 */
 		regs->orig_ax = value;
-		if (syscall_get_nr(child, regs) >= 0)
-			task_thread_info(child)->status |= TS_COMPAT;
 		break;
 
 	case offsetof(struct user32, regs.eflags):
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2016-06-21 19:01 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-18 10:21 [PATCH] x86/ptrace: Remove questionable TS_COMPAT usage in ptrace Andy Lutomirski
2016-06-18 13:55 ` Pedro Alves
2016-06-18 14:41   ` Pedro Alves
2016-06-18 17:02   ` Andy Lutomirski
2016-06-19 22:09     ` Andy Lutomirski
2016-06-20 10:27       ` Pedro Alves
2016-06-20 15:24       ` Oleg Nesterov
2016-06-20 16:30         ` Andy Lutomirski
2016-06-20 16:14           ` Oleg Nesterov
2016-06-20 17:25             ` Andy Lutomirski
2016-06-20 10:07     ` Pedro Alves
2016-06-20 11:12       ` Jan Kratochvil
2016-06-18 17:48 ` Kees Cook
2016-06-19 21:19 ` Oleg Nesterov
2016-06-19 22:23   ` Andy Lutomirski
2016-06-20  6:12   ` Andy Lutomirski
2016-06-20 15:31     ` Oleg Nesterov
2016-06-20 17:53     ` the usage of __SYSCALL_MASK in entry_SYSCALL_64/do_syscall_64 is not consistent Oleg Nesterov
2016-06-21 19:01       ` Kees Cook

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).