linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andrew Lutomirski <luto@MIT.EDU>
To: Ingo Molnar <mingo@elte.hu>
Cc: richard -rw- weinberger <richard.weinberger@gmail.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Adrian Bunk <bunk@stusta.de>,
	"H. Peter Anvin" <hpa@linux.intel.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>,
	x86@kernel.org, linux-kernel@vger.kernel.org
Subject: [RFC] fixing the UML failure root cause
Date: Tue, 11 Oct 2011 10:24:25 -0700	[thread overview]
Message-ID: <4E947BC9.7040805@mit.edu> (raw)
In-Reply-To: <20111011062253.GA3589@elte.hu>

[-- Attachment #1: Type: text/plain, Size: 1259 bytes --]

On 10/10/2011 11:22 PM, Ingo Molnar wrote:
> 
> * Andrew Lutomirski <luto@mit.edu> wrote:
> 
>>> Andrew?
>>
>> I think I know what the root cause is and I have most of a patch to 
>> fix it.  It doesn't compile (yet), it's a little less trivial than 
>> I'd like for something this late in the -rc cycle, and it adds 16 
>> bytes to thread_struct (ugh!).
>>
>> I think I can make a follow-up patch that removes 32 bytes of 
>> per-thread state to restore my karma, though, but that will 
>> definitely not be 3.1 material.
> 
> Ok, i've queued up the vsyscall=native patch in tip:x86/urgent for 
> now - we can re-try in v3.2 (perhaps) if a satisfactory solution is 
> found.

Getting full cause information for uaccess failure was messy enough that
I gave up.  There are a *lot* of uaccess failure paths to work through.

So here's a different approach.  It's not perfect: it always blames
SEGV_MAPERR instead of SEGV_ACCERR.  I implemented it for vgettimeofday
but not the other two vsyscalls.

What do you think of this approach?  If it seems good, I'll finish the
patch and submit it.

With this patch applied, UML appears to work, but it fills the log with
exploit attempt warnings.  Any ideas on what to do about that?

--Andy

> 
> Thanks,
> 
> 	Ingo


[-- Attachment #2: vsyscall_hack.patch --]
[-- Type: text/plain, Size: 3033 bytes --]

diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 18ae83d..c0bafec 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -139,6 +139,42 @@ static int addr_to_vsyscall_nr(unsigned long addr)
 	return nr;
 }
 
+/* Copy data to user space, forcing signals on failure. */
+static int copy_to_user_sig(unsigned long dest, const void *src, size_t len)
+{
+	/*
+	 * This may be the slowest memcpy ever written.  We don't really care.
+	 */
+	size_t i;
+	for (i = 0; i < len; i++) {
+		char __user *user_byte = (char __user *)(dest + i);
+		if (put_user(((char*)src)[i], user_byte) != 0) {
+			/* Report full siginfo and context */
+			struct task_struct *tsk = current;
+			siginfo_t info;
+			memset(&info, 0, sizeof(info));
+			info.si_signo = SIGSEGV;
+			/*
+			 * Could be SEGV_ACCERR -- we don't distinguish it
+			 * correctly.
+			 */
+			info.si_code = SEGV_MAPERR;
+			info.si_addr = user_byte;
+			/*
+			 * Write fault in user mode.  We don't distinguish
+			 * protection fault from no page found.
+			 */
+			tsk->thread.error_code = 6;
+			tsk->thread.cr2 = (unsigned long)user_byte;
+			tsk->thread.trap_no = 14;
+			force_sig_info(SIGSEGV, &info, tsk);
+			return -EFAULT;
+		}
+	}
+
+	return 0;
+}
+
 bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
 {
 	struct task_struct *tsk;
@@ -181,10 +217,19 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
 
 	switch (vsyscall_nr) {
 	case 0:
-		ret = sys_gettimeofday(
-			(struct timeval __user *)regs->di,
-			(struct timezone __user *)regs->si);
+	{
+		struct timeval tv;
+		do_gettimeofday(&tv);
+
+		if (regs->di && copy_to_user_sig(regs->di, &tv, sizeof(tv)))
+			goto warn_fault;
+		if (regs->si && copy_to_user_sig(regs->si, &sys_tz,
+		                                 sizeof(struct timezone)))
+			goto warn_fault;
+
+		ret = 0;
 		break;
+	}
 
 	case 1:
 		ret = sys_time((time_t __user *)regs->di);
@@ -197,19 +242,6 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
 		break;
 	}
 
-	if (ret == -EFAULT) {
-		/*
-		 * Bad news -- userspace fed a bad pointer to a vsyscall.
-		 *
-		 * With a real vsyscall, that would have caused SIGSEGV.
-		 * To make writing reliable exploits using the emulated
-		 * vsyscalls harder, generate SIGSEGV here as well.
-		 */
-		warn_bad_vsyscall(KERN_INFO, regs,
-				  "vsyscall fault (exploit attempt?)");
-		goto sigsegv;
-	}
-
 	regs->ax = ret;
 
 	/* Emulate a ret instruction. */
@@ -221,6 +253,19 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
 sigsegv:
 	force_sig(SIGSEGV, current);
 	return true;
+
+warn_fault:
+	/*
+	 * Bad news -- userspace fed a bad pointer to a vsyscall.
+	 *
+	 * With a real vsyscall, that would have caused SIGSEGV.
+	 * To make writing reliable exploits using the emulated
+	 * vsyscalls harder, generate SIGSEGV here as well.
+	 */
+
+	warn_bad_vsyscall(KERN_INFO, regs,
+	                  "vsyscall fault (exploit attempt?)");
+	return true;
 }
 
 /*

  reply	other threads:[~2011-10-11 17:24 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-10-03  9:08 [3.1 patch] x86: default to vsyscall=native Adrian Bunk
2011-10-03 13:04 ` Andrew Lutomirski
2011-10-03 17:33   ` Adrian Bunk
2011-10-03 18:06     ` Andrew Lutomirski
2011-10-03 18:41       ` Adrian Bunk
2011-10-05 22:13     ` Andrew Lutomirski
2011-10-05 22:22       ` richard -rw- weinberger
2011-10-05 22:30         ` Adrian Bunk
2011-10-05 22:41           ` richard -rw- weinberger
2011-10-05 22:46           ` Andrew Lutomirski
2011-10-05 23:36             ` Andrew Lutomirski
2011-10-06  3:06               ` Andrew Lutomirski
2011-10-06 12:12                 ` richard -rw- weinberger
2011-10-06 15:37                 ` richard -rw- weinberger
2011-10-06 18:16                   ` Andrew Lutomirski
2011-10-06 18:34                     ` Linus Torvalds
2011-10-07  0:48                       ` Andrew Lutomirski
2011-10-10 11:19                         ` richard -rw- weinberger
2011-10-10 11:48                           ` Ingo Molnar
2011-10-10 15:31                             ` Andrew Lutomirski
2011-10-11  6:22                               ` Ingo Molnar
2011-10-11 17:24                                 ` Andrew Lutomirski [this message]
2011-10-13  6:19                                   ` [RFC] fixing the UML failure root cause Linus Torvalds
2011-10-13  8:40                                     ` Andrew Lutomirski
2011-10-14  4:46                                       ` Linus Torvalds
2011-10-14  6:30                                         ` Andrew Lutomirski
2011-10-14 20:10                                           ` Linus Torvalds
2011-10-21 21:01                                             ` [PATCH] x86-64: Set siginfo and context on vsyscall emulation faults Andy Lutomirski
2011-10-22  4:46                                               ` Linus Torvalds
2011-10-22  9:07                                                 ` Andy Lutomirski
2011-11-08  0:33                                                   ` [PATCH 0/2] Fix and re-enable vsyscall=emulate Andy Lutomirski
2011-11-08  0:33                                                     ` [PATCH 1/2] x86-64: Set siginfo and context on vsyscall emulation faults Andy Lutomirski
2011-12-05 13:23                                                       ` [tip:x86/asm] " tip-bot for Andy Lutomirski
2011-11-08  0:33                                                     ` [PATCH 2/2] x86: Default to vsyscall=emulate Andy Lutomirski
2011-12-05 13:24                                                       ` [tip:x86/asm] " tip-bot for Andy Lutomirski
2011-12-02 22:47                                                     ` [PATCH 0/2] Fix and re-enable vsyscall=emulate Andy Lutomirski
2011-12-05 11:18                                                       ` H. Peter Anvin
2011-10-14 19:53                                   ` [RFC] fixing the UML failure root cause richard -rw- weinberger
2011-10-14 20:17                                     ` Andrew Lutomirski
2011-10-14 20:23                                       ` richard -rw- weinberger
2011-10-14 20:31                                         ` Andrew Lutomirski
2011-10-14 20:39                                           ` richard -rw- weinberger
2011-10-14 22:28                                       ` richard -rw- weinberger
2011-10-15 16:57                                         ` Ingo Molnar
2011-10-05 22:24       ` [3.1 patch] x86: default to vsyscall=native Adrian Bunk
2011-10-03 13:19 ` richard -rw- weinberger
2011-10-03 17:46   ` Adrian Bunk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4E947BC9.7040805@mit.edu \
    --to=luto@mit.edu \
    --cc=bunk@stusta.de \
    --cc=hpa@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=mingo@redhat.com \
    --cc=richard.weinberger@gmail.com \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).