forked from pool/xorg-x11-server
50 lines
2.0 KiB
Diff
50 lines
2.0 KiB
Diff
commit a9e20306fbe3262602f21b876a52a1ef38cdf20a
|
|
Author: Egbert Eich <eich@ovid.suse.de>
|
|
Date: Fri Nov 21 18:50:01 2008 +0100
|
|
|
|
int10: Do an mprotect(..,PROT_EXEC) on shmat()ed memory ranges.
|
|
|
|
When the linux kernel sets the NX bit vm86 segfaults when it tries to execute
|
|
code in memory that is not marked EXEC. Such code gets called whenever
|
|
we return from a VBIOS call to signal the calling program that the call
|
|
is actually finished and that we are not trapping for other reasons (like
|
|
IO accesses).
|
|
Use mprotect(2) to set these memory ranges PROT_EXEC.
|
|
|
|
diff --git a/hw/xfree86/os-support/linux/int10/linux.c b/hw/xfree86/os-support/linux/int10/linux.c
|
|
index 67eb161..b15f7fd 100644
|
|
--- a/hw/xfree86/os-support/linux/int10/linux.c
|
|
+++ b/hw/xfree86/os-support/linux/int10/linux.c
|
|
@@ -1,6 +1,6 @@
|
|
/*
|
|
* linux specific part of the int10 module
|
|
- * Copyright 1999, 2000, 2001, 2002, 2003, 2004 Egbert Eich
|
|
+ * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2008 Egbert Eich
|
|
*/
|
|
#ifdef HAVE_XORG_CONFIG_H
|
|
#include <xorg-config.h>
|
|
@@ -357,7 +357,10 @@ MapCurrentInt10(xf86Int10InfoPtr pInt)
|
|
"shmat(low_mem) error: %s\n",strerror(errno));
|
|
return FALSE;
|
|
}
|
|
-
|
|
+ if (mprotect((void*)0, V_RAM, PROT_READ|PROT_WRITE|PROT_EXEC) != 0)
|
|
+ xf86DrvMsg(pInt->scrnIndex, X_ERROR,
|
|
+ "Cannot set EXEC bit on low memory: %s\n", strerror(errno));
|
|
+
|
|
if (((linuxInt10Priv*)pInt->private)->highMem >= 0) {
|
|
addr = shmat(((linuxInt10Priv*)pInt->private)->highMem,
|
|
(char*)HIGH_MEM, 0);
|
|
@@ -368,6 +371,11 @@ MapCurrentInt10(xf86Int10InfoPtr pInt)
|
|
"shmget error: %s\n",strerror(errno));
|
|
return FALSE;
|
|
}
|
|
+ if (mprotect((void*)HIGH_MEM, HIGH_MEM_SIZE,
|
|
+ PROT_READ|PROT_WRITE|PROT_EXEC) != 0)
|
|
+ xf86DrvMsg(pInt->scrnIndex, X_ERROR,
|
|
+ "Cannot set EXEC bit on high memory: %s\n",
|
|
+ strerror(errno));
|
|
} else {
|
|
if ((fd = open(DEV_MEM, O_RDWR, 0)) >= 0) {
|
|
if (mmap((void *)(V_BIOS), SYS_BIOS - V_BIOS,
|