Skip to contentSkip to conversation

x86: default to vsyscall=native

PATCH NAK Adrian Bunk 2 participants 4 messages Oct 5, 2011 – Oct 9, 2011

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 x86: default to vsyscall=native

After upgrading a kernel the existing userspace should just work (assuming it did work before ;-) ), but when I upgraded my kernel from 3.0.4 to 3.1.0-rc8 a UML instance didn't come up properly.

dmesg said:
linux-2.6.30.1[3800] vsyscall fault (exploit attempt?) ip:ffffffffff600000 cs:33 sp:7fbfb9c498 ax:ffffffffff600000 si:0 di:606790 linux-2.6.30.1[3856] vsyscall fault (exploit attempt?) ip:ffffffffff600000 cs:33 sp:7fbfb13168 ax:ffffffffff600000 si:0 di:606790

Looking throught the changelog I ended up at commit 3ae36655 ("x86-64: Rework vsyscall emulation and add vsyscall= parameter").

Linus suggested in https://lkml.org/lkml/2011/8/9/376 to default to vsyscall=native.

That sounds reasonable to me, and fixes the problem for me.

---
 Documentation/kernel-parameters.txt |    7 ++++---
 arch/x86/kernel/vsyscall_64.c       |    2 +-
 2 files changed, 5 insertions(+), 4 deletions(-)
Documentation/kernel-parameters.txt +4 -3
index 854ed5ca..d6e6724 100644
@@ -2706,10 +2706,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			functions are at fixed addresses, they make nice
 			targets for exploits that can control RIP.
 
-			emulate     [default] Vsyscalls turn into traps and are
-			            emulated reasonably safely.
+			emulate     Vsyscalls turn into traps and are emulated
+			            reasonably safely.
 
-			native      Vsyscalls are native syscall instructions.
+			native      [default] Vsyscalls are native syscall
+			            instructions.
 			            This is a little bit faster than trapping
 			            and makes a few dynamic recompilers work
 			            better than they would in emulation mode.
arch/x86/kernel/vsyscall_64.c +1 -1
index 18ae83d..b56c65de 100644
@@ -56,7 +56,7 @@ DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data) =
 	.lock = __SEQLOCK_UNLOCKED(__vsyscall_gtod_data.lock),
 };
 
-static enum { EMULATE, NATIVE, NONE } vsyscall_mode = EMULATE;
+static enum { EMULATE, NATIVE, NONE } vsyscall_mode = NATIVE;
 
 static int __init vsyscall_setup(char *str)
 {
Signature · 1 line
1.7.6.3
#1 lore raw
Quoted 8 lines · Adrian Bunk

After upgrading a kernel the existing userspace should just work (assuming it did work before ;-) ), but when I upgraded my kernel from 3.0.4 to 3.1.0-rc8 a UML instance didn't come up properly.

dmesg said:
linux-2.6.30.1[3800] vsyscall fault (exploit attempt?) ip:ffffffffff600000 cs:33 sp:7fbfb9c498 ax:ffffffffff600000 si:0 di:606790 linux-2.6.30.1[3856] vsyscall fault (exploit attempt?) ip:ffffffffff600000 cs:33 sp:7fbfb13168 ax:ffffffffff600000 si:0 di:606790

Quoted 7 lines

Looking throught the changelog I ended up at commit 3ae36655 ("x86-64: Rework vsyscall emulation and add vsyscall= parameter").

Linus suggested in https://lkml.org/lkml/2011/8/9/376 to default to vsyscall=native.

That sounds reasonable to me, and fixes the problem for me.

NAK.

We have way too long listened to people who insisted that we keep all known security holes open by default for the sake of backwards compatibility.

Default wants to be restricted and not the other way round. Forcing people to loosen restrictions makes them aware of the problem. Not doing so keeps them in the illusion that stuff is just safe to use.

We might need better dmesg output, e.g.

printk_once("you might run something which requires
vsyscall=native, but be aware that you are opening a security hole. See Documentation/....")

That's fine, but making the defaults insecure is just ass backwards.

Thanks,

tglx

#2 lore raw
Quoted 8 lines · Thomas Gleixner

...
We might need better dmesg output, e.g.

printk_once("you might run something which requires
vsyscall=native, but be aware that you are opening a security hole. See Documentation/....")

That's fine, but making the defaults insecure is just ass backwards.

Better dmesg output is in any case a better idea, patch is coming.

I stayed with warn_bad_vsyscall() instead of printk_once() for the following reasons:
- _once is bad for something that might indicate exploit attempts, warn_bad_vsyscall() is already ratelimited
- the name and pid of the process should be shown
- the additional output of warn_bad_vsyscall() can help determine what caused it

Quoted 3 lines

Thanks,

tglx

cu
Adrian

Signature · 4 lines
       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed
#3 lore raw

PATCH 1/1 x86 vsyscall_64.c: better error message on bad pointers

At least some UML versions run into this and need vsyscall=native for now.

---
 arch/x86/kernel/vsyscall_64.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
arch/x86/kernel/vsyscall_64.c +1 -1
index 18ae83d..4ab7e32 100644
@@ -206,7 +206,7 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)
 		 * vsyscalls harder, generate SIGSEGV here as well.
 		 */
 		warn_bad_vsyscall(KERN_INFO, regs,
-				  "vsyscall fault (exploit attempt?)");
+				  "vsyscall fault (exploit attempt?) - if this is a legitimate program boot with vsyscall=native (read kernel-parameters.txt for the security implications)");
 		goto sigsegv;
 	}