]>
Commit | Line | Data |
---|---|---|
8b74c0c1 AM |
1 | commit a9e20306fbe3262602f21b876a52a1ef38cdf20a |
2 | Author: Egbert Eich <eich@ovid.suse.de> | |
3 | Date: Fri Nov 21 18:50:01 2008 +0100 | |
4 | ||
5 | int10: Do an mprotect(..,PROT_EXEC) on shmat()ed memory ranges. | |
6 | ||
7 | When the linux kernel sets the NX bit vm86 segfaults when it tries to execute | |
8 | code in memory that is not marked EXEC. Such code gets called whenever | |
9 | we return from a VBIOS call to signal the calling program that the call | |
10 | is actually finished and that we are not trapping for other reasons (like | |
11 | IO accesses). | |
12 | Use mprotect(2) to set these memory ranges PROT_EXEC. | |
13 | ||
14 | diff --git a/hw/xfree86/os-support/linux/int10/linux.c b/hw/xfree86/os-support/linux/int10/linux.c | |
15 | index 67eb161..b15f7fd 100644 | |
16 | --- a/hw/xfree86/os-support/linux/int10/linux.c | |
17 | +++ b/hw/xfree86/os-support/linux/int10/linux.c | |
18 | @@ -1,6 +1,6 @@ | |
19 | /* | |
20 | * linux specific part of the int10 module | |
21 | - * Copyright 1999, 2000, 2001, 2002, 2003, 2004 Egbert Eich | |
22 | + * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2008 Egbert Eich | |
23 | */ | |
24 | #ifdef HAVE_XORG_CONFIG_H | |
25 | #include <xorg-config.h> | |
26 | @@ -357,7 +357,10 @@ MapCurrentInt10(xf86Int10InfoPtr pInt) | |
27 | "shmat(low_mem) error: %s\n",strerror(errno)); | |
28 | return FALSE; | |
29 | } | |
30 | - | |
31 | + if (mprotect((void*)0, V_RAM, PROT_READ|PROT_WRITE|PROT_EXEC) != 0) | |
32 | + xf86DrvMsg(pInt->scrnIndex, X_ERROR, | |
33 | + "Cannot set EXEC bit on low memory: %s\n", strerror(errno)); | |
34 | + | |
35 | if (((linuxInt10Priv*)pInt->private)->highMem >= 0) { | |
36 | addr = shmat(((linuxInt10Priv*)pInt->private)->highMem, | |
37 | (char*)HIGH_MEM, 0); | |
38 | @@ -368,6 +371,11 @@ MapCurrentInt10(xf86Int10InfoPtr pInt) | |
39 | "shmget error: %s\n",strerror(errno)); | |
40 | return FALSE; | |
41 | } | |
42 | + if (mprotect((void*)HIGH_MEM, HIGH_MEM_SIZE, | |
43 | + PROT_READ|PROT_WRITE|PROT_EXEC) != 0) | |
44 | + xf86DrvMsg(pInt->scrnIndex, X_ERROR, | |
45 | + "Cannot set EXEC bit on high memory: %s\n", | |
46 | + strerror(errno)); | |
47 | } else { | |
48 | if ((fd = open(DEV_MEM, O_RDWR, 0)) >= 0) { | |
49 | if (mmap((void *)(V_BIOS), SYS_BIOS - V_BIOS, |