lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <87fuv685kl.fsf@rustcorp.com.au>
Date:	Fri, 01 Apr 2016 12:15:46 +1030
From:	Rusty Russell <rusty@...abs.org>
To:	Andy Lutomirski <luto@...nel.org>, x86@...nel.org
Cc:	linux-kernel@...r.kernel.org, Brian Gerst <brgerst@...il.com>,
	Borislav Petkov <bp@...en8.de>,
	Frédéric Weisbecker <fweisbec@...il.com>,
	Denys Vlasenko <dvlasenk@...hat.com>,
	Linus Torvalds <torvalds@...ux-foundation.org>,
	Andy Lutomirski <luto@...nel.org>,
	"x86\@kernel.org" <x86@...nel.org>
Subject: Re: [PATCH 11/12] x86/entry/32: Change INT80 to be an interrupt gate

Andy Lutomirski <luto@...nel.org> writes:
> I want all of the syscall entries to run with interrupts off so that
> I can efficiently run context tracking before enabling interrupts.
>
> This will regress int $0x80 performance on 32-bit kernels by a
> couple of cycles.  This shouldn't matter much -- int $0x80 is not a
> fast path.
>
> This effectively reverts 657c1eea0019 ("x86/entry/32: Fix
> entry_INT80_32() to expect interrupts to be on") and fixes the issue
> differently.
>
> Signed-off-by: Andy Lutomirski <luto@...nel.org>

This broke lguest.  Wow, diving into that code again was a bit of a
trip.

Thanks!
Rusty.
---
From: Rusty Russell <rusty@...tcorp.com.au>
Subject: lguest: fix handling of guest syscalls using interrupt gates.

In a798f091113e ("x86/entry/32: Change INT80 to be an interrupt gate")
Andy broke lguest.  This is because lguest had special code to allow
the 0x80 trap gate go straight into the guest itself; interrupts gates
(without more work, as mentioned in the file's comments) bounce via
the hypervisor.

His change made them go via the hypervisor, but as it's in the range of
normal hardware interrupts, they were not directed through to the guest
at all.  Turns out the guest userspace isn't very effective if syscalls
are all noops.

I haven't ripped out all the now-useless trap-direct-to-guest-kernel
code yet, since it will still be needed if someone decides to update
this optimization.

Signed-off-by: Rusty Russell <rusty@...tcorp.com.au>

diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c
index eb934b0242e0..ab1535f032c2 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -331,7 +331,7 @@ void set_interrupt(struct lg_cpu *cpu, unsigned int irq)
  * Actually now I think of it, it's possible that Ron *is* half the Plan 9
  * userbase.  Oh well.
  */
-static bool could_be_syscall(unsigned int num)
+bool could_be_syscall(unsigned int num)
 {
 	/* Normal Linux IA32_SYSCALL_VECTOR or reserved vector? */
 	return num == IA32_SYSCALL_VECTOR || num == syscall_vector;
@@ -416,6 +416,10 @@ bool deliver_trap(struct lg_cpu *cpu, unsigned int num)
  *
  * This routine indicates if a particular trap number could be delivered
  * directly.
+ *
+ * Unfortunately, Linux 4.6 started using an interrupt gate instead of a
+ * trap gate for syscalls, so this trick is ineffective.  See Mastery for
+ * how we could do this anyway...
  */
 static bool direct_trap(unsigned int num)
 {
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index ac8ad0461e80..69b3814afd2f 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -167,6 +167,7 @@ void guest_set_clockevent(struct lg_cpu *cpu, unsigned long delta);
 bool send_notify_to_eventfd(struct lg_cpu *cpu);
 void init_clockdev(struct lg_cpu *cpu);
 bool check_syscall_vector(struct lguest *lg);
+bool could_be_syscall(unsigned int num);
 int init_interrupts(void);
 void free_interrupts(void);
 
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index 6a4cd771a2be..adc162c7040d 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -429,8 +429,12 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
 			return;
 		break;
 	case 32 ... 255:
+		/* This might be a syscall. */
+		if (could_be_syscall(cpu->regs->trapnum))
+			break;
+
 		/*
-		 * These values mean a real interrupt occurred, in which case
+		 * Other values mean a real interrupt occurred, in which case
 		 * the Host handler has already been run. We just do a
 		 * friendly check if another process should now be run, then
 		 * return to run the Guest again.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ