Page 1 of 1

PAX not playing nice...

PostPosted: Sun Oct 20, 2002 3:22 pm
by CheshireCat
I've turned off all PAX restrictions for XFree86, but PAX still kills it as soon as it tries to load any modules.

Code: Select all
chshrcat# chpax -v /usr/X11R6/bin/XFree86
/usr/X11R6/bin/XFree86: PAGE_EXEC is disabled, trampolines are emulated, mprotect() is not restricted, mmap() base is not randomized


/var/log/XFree86.0.log contains the following:
Code: Select all
XFree86 Version 4.2.0 / X Window System
(protocol Version 11, revision 0, vendor release 6600)
Release Date: 18 January 2002
        If the server is older than 6-12 months, or if your card is
        newer than the above date, look for a newer version before
        reporting problems.  (See http://www.XFree86.Org/)
Build Operating System: Linux 2.4.19-xfs-r1 i586 [ELF]
Module Loader present
Markers: (--) probed, (**) from config file, (==) default setting,
         (++) from command line, (!!) notice, (II) informational,
         (WW) warning, (EE) error, (NI) not implemented, (??) unknown.
(==) Log file: "/var/log/XFree86.0.log", Time: Sun Oct 20 14:57:56 2002
(==) Using config file: "/etc/X11/XF86Config"
(==) ServerLayout "XFree86 Configured"
(**) |-->Screen "Screen0" (0)
(**) |   |-->Monitor "Monitor0"
(**) |   |-->Device "Card0"
(**) |-->Input Device "Mouse0"
(**) |-->Input Device "Keyboard0"
(**) Option "XkbRules" "xfree86"
(**) XKB: rules: "xfree86"
(**) Option "XkbModel" "kensiko"
(**) XKB: model: "kensiko"
(**) Option "XkbLayout" "us"
(**) XKB: layout: "us"
(==) Keyboard: CustomKeycode disabled
(**) FontPath set to "/usr/X11R6/lib/X11/fonts/misc/,/usr/X11R6/lib/X11/fonts/Speedo/,/usr/X11R6/lib/X11/fonts/Type1/,/usr/X11R6/lib/X11/fonts/CID/,/usr/X11R6/lib/X11/fonts/75dpi/,/usr/X11R6/lib/X11/fonts/freefont/,/usr/X11R6/lib/X11/fonts/lfp-fix/,/usr/X11R6/lib/X11/fonts/lfp-var/,/usr/X11R6/lib/X11/fonts/sharefont/,/usr/X11R6/lib/X11/fonts/truetype/,/usr/X11R6/lib/X11/fonts/TTF/,/usr/X11R6/lib/X11/fonts/local/truetype"
(**) RgbPath set to "/usr/X11R6/lib/X11/rgb"
(**) ModulePath set to "/usr/X11R6/lib/modules"
(--) using VT number 7

(WW) Open APM failed (/dev/apm_bios) (No such file or directory)
(II) Module ABI versions:
        XFree86 ANSI C Emulation: 0.1
        XFree86 Video Driver: 0.5
        XFree86 XInput driver : 0.3
        XFree86 Server Extension : 0.1
        XFree86 Font Renderer : 0.3
(II) Loader running on linux
(II) LoadModule: "bitmap"
(II) Loading /usr/X11R6/lib/modules/fonts/libbitmap.a
(II) Module bitmap: vendor="The XFree86 Project"
        compiled for 4.2.0, module version = 1.0.0
        Module class: XFree86 Font Renderer
        ABI class: XFree86 Font Renderer, version 0.3


And dmesg shows that XFree86 was terminated by PAX:
Code: Select all
PAX: terminating task: /usr/X11R6/bin/XFree86(XFree86):20079, uid/euid: 0/0, EIP: 0820D1A8, ESP: 5FFFFB8C
PAX: bytes at EIP: 55 89 e5 83 ec 14 8b 45 08 68 10 d2 20 08 a3 18 d2 20 08 e8


I'm running gentoo, and using the kernel from gentoo-sources-2.4.19-r10, which includes grsec 1.9.7. I noticed there are some bug fixes between 1.9.7 and 1.9.7d, so I got the diff between them from CVS and merged that in as well, but I'm still having no luck. Any idea what I might be missing?[/code]

PostPosted: Sun Oct 20, 2002 8:11 pm
by spender
you need to download the updated chpax from http://pageexec.virtualave.net. Your version of chpax doesn't support segmexec, which is why PaX is still operating on the binary.
-Brad

Re: PAX not playing nice...

PostPosted: Mon Oct 21, 2002 5:34 am
by PaX Team
CheshireCat wrote:I've turned off all PAX restrictions for XFree86, but PAX still kills it as soon as it tries to load any modules.

Code: Select all
chshrcat# chpax -v /usr/X11R6/bin/XFree86
/usr/X11R6/bin/XFree86: PAGE_EXEC is disabled, trampolines are emulated, mprotect() is not restricted, mmap() base is not randomized

As Brad's said it already, your chpax is of an older version that doesn't let you control the new non-executable page implementation (SEGMEXEC) which is enabled by default (instead of PAGEEXEC).

There is another solution for XFree86 however and i'd like you (and/or others) to try it out and if it works out as well as it did here, i'll publish it on the site. The goal is to build a statically linked X server binary, this would solve the problem because X would no longer want to create executable code on the fly and as a nice side effect, all of the PaX protection would apply to it as well. So to build a statically linked X put the following line into your xc/config/cf/host.def file:

Code: Select all
#define DoLoadableServer NO


then build your X server ('make World' or whatever way your distribution works). The resulting X binary will be around 7 MB (if you created an ET_DYN one, it would be almost 9 MB). Install it normally and off you go (but do make a backup copy of the old server binary first, just in case).

Chpax did it...

PostPosted: Mon Oct 21, 2002 12:34 pm
by CheshireCat
The updated chpax took care of things. Gentoo actually gave me an init script that runs chpax on boot, not sure why since it looks like chpax marked the file permanently. At the moment, I don't want PaX on X badly enough to rebuild it as static. Just out of curiosity, why a separate flag for each type of PAGE_EXEC enforcement? Is it possible to build both into the kernel, and select one for each executable (say, using the paging-based one for apps that need too much memory for the segmentation-based system?). If so, which one is used by default if an executable has not been modified? Also, this is just a thought, but how hard would it be to patch X to get around the PaX problems with loadable modules? Perhaps by using mprotect on the pages the module loads into, or mmaping the module file. Even adding an mprotect call and disabling mprotect restrictions would give you a more secure modular X than you can get now, right?

Chpax did it...

PostPosted: Mon Oct 21, 2002 12:48 pm
by CheshireCat
The updated chpax took care of things. Gentoo actually gave me an init script that runs chpax on boot, not sure why since it looks like chpax marked the file permanently. At the moment, I don't want PaX on X badly enough to rebuild it as static. Just out of curiosity, why a separate flag for each type of PAGE_EXEC enforcement? Is it possible to build both into the kernel, and select one for each executable (say, using the paging-based one for apps that need too much memory for the segmentation-based system?). If so, which one is used by default if an executable has not been modified? Also, this is just a thought, but how hard would it be to patch X to get around the PaX problems with loadable modules? Perhaps by using mprotect on the pages the module loads into, or mmaping the module file, or replacing the calloc with an anonymous mmap? Even adding an mprotect call and disabling mprotect restrictions would give you a more secure modular X than you can get now, right?

Re: Chpax did it...

PostPosted: Mon Oct 21, 2002 3:22 pm
by PaX Team
Just out of curiosity, why a separate flag for each type of PAGE_EXEC enforcement?
how else would you be able to differentiate/choose between the two? the problem is, you have 3 'states' (PAGEEXEC/SEGMEXEC/neither is active on a given executable) so you need 2 bits to encode it.
Is it possible to build both into the kernel, and select one for each executable (say, using the paging-based one for apps that need too much memory for the segmentation-based system?).
of course it is, every configuration combination is valid that the kernel configure systems allows you to choose (this was carefully set up this way, even if it resulted in quite some 'mess' of #ifdefs in certain files).
If so, which one is used by default if an executable has not been modified?
SEGMEXEC, as decided by the logic in fs/binfmt_elf.c where the ELF header flags are translated into the PaX specific task flags.
Also, this is just a thought, but how hard would it be to patch X to get around the PaX problems with loadable modules? Perhaps by using mprotect on the pages the module loads into, or mmaping the module file, or replacing the calloc with an anonymous mmap? Even adding an mprotect call and disabling mprotect restrictions would give you a more secure modular X than you can get now, right?

1. mprotect won't work (unless you disable the restrictions, but that reduces 'security', although still better than having no PaX on X at all).

2. direct mmap() or better, just using the already existing/working dlopen() interface would work, but the problem is that the XFree86 guys decided to support ET_REL ELF files as well, which dlopen() doesn't handle. you have two ways to solve this problem: either change X (makefiles + some code) to create ET_DYN shared libraries where it now creates simple .a archives of ET_REL ELF files (then X's existing ET_DYN loader would work fine since it uses dlopen()) or rewrite the existing ET_REL ELF loader code to use mmap() and not malloc() and family.

Anonymous mmap probably easiest?

PostPosted: Mon Oct 21, 2002 6:14 pm
by CheshireCat
I wonder which would be easiest... If there's not a whole lot of code duplication, fixing the ET_REL loader should be pretty trivial, right? Thinking about it now, my anonymous mmap idea wasn't so hot, as it would either require mprotect (to make the pages write-protected after loading the module into them), or would leave the pages unprotected (not much better than disabling PaX). So the options are pretty much to have all of the ET_REL files it builds linked as ET_DYN, or rewrite the ET_REL loader to mmap them... if I get bored enough maybe I'll see how hard it would be. :-)

Re: Anonymous mmap probably easiest?

PostPosted: Mon Oct 21, 2002 7:47 pm
by PaX Team
CheshireCat wrote:I wonder which would be easiest... If there's not a whole lot of code duplication, fixing the ET_REL loader should be pretty trivial, right?
it's not that trivial given that the mmap() interface has a different semantics than malloc(). eg. former wants 4k (page size) aligned addresses and file offsets. also IIRC the ET_REL loader uses realloc() which is again not the same as mremap().
Thinking about it now, my anonymous mmap idea wasn't so hot, as it would either require mprotect (to make the pages write-protected after loading the module into them), or would leave the pages unprotected (not much better than disabling PaX).
anonymous mmap() would not work for a different reason: if MPROTECT is enabled, you cannot make such mappings executable at all. and if you use file mappings, you will have a problem with relocations on the executable pages: the current logic would allow an mprotect(PROT_WRITE) only if the given region is an ET_DYN mapping and its dynamic segment has a DT_TEXTREL entry. hmm, now that i think about it, this actually means that the ET_REL loader cannot be fixed, so that leaves only one solution...