Saturday, 25 June 2011

Firefox 5 with MPROTECT on...of course!

While the Firefox 4 ebuild is still warm, here comes Firefox 5! And yes - we want MPROTECT enabled on it too of course...! ;)

BTW, if you've ever wondered why I'm so preoccupied about the whole mrprotect story, I recommend reading my year old research on the topic which can be found here.

Well, it turns out to be, that with the release of the new Firefox things got much easier actually! There is no need to patch the source anymore, we just need to disable the 'jit' during source configuration. Not only this allows us to actually compile Firefox 5 on Gentoo hardened (sic!) but actually allows to run it with mprotect enabled too! But first things first...

An attempt to install Firefox 5 on Gentoo Hardened system is likely to end up with emerge failing and entry in kern.log similar to this:

grsec: denied RWX mmap of by /var/tmp/portage/www-client/firefox-5.0/work/mozilla-release/obj-x86_64-unknown-linux-gnu/dist/bin/xpcshell[xpcshell:10891] uid/euid:0/0 gid/egid:0/0, parent /bin/bash[sh:10882] uid/euid:0/0 gid/egid:0/0
xpcshell[10891]: segfault at 41ea0ddc ip 00006b9475051ed4 sp 000078b37e81b6f0 error 4 in libxul.so[6b9474031000+1823000]

While jit seems to like RWX memory pages a lot, Gentoo hardened users do not...;)

But fear not! The trustworthy hack for Firefox 4 works here too, and we don't need to hack the source, it's just enough to add --disable-methodjit the configure script. (For more information on how to create your local overlay have a look at my previous post or refer to your favourite search engine ;) . So basically you could add this to the ebuild, somewhere in the src_configure() section:

if ! use jit ; then
mozconfig_annotate '' --disable-methodjit
fi

..recompile...and off you go! At the moment the firefox binary (/usr/lib/firefox/firefox-bin) is quite likely to have mprotect automatically disabled so you might need to enable it by hand by running:

paxctl -M /usr/lib/firefox/firefox-bin

Bear in mind that Firefox now runs plugins in a separate process - plugin-container. It can also be mprotect enabled or disabled, so you might want to check it too...it's worth noting that enabling mprotect on plugin-container will make Firefox crash probably on every use of Flash or Java, but hey, it's secure then, is it not...? ;)

Gentoo bug tracking all this can be found here.

Monday, 13 June 2011

Enabling MPROTECT on Firefox 4

...so after nearly a year (sic!), here's the solution to get MPROTECT working with Firefox - browsing the Interwebs can be secure again! ;) Thanks to zakalwe on #grsecurity@OFTC for the patch and help! :)


So the problem of course is JIT - we need to disable it at all cost! (You'll be probably losing some JS performance, ya've been warned!). Well, it's not the most elegant solution, but it does work...The elegant solution would be of course to have an compilation option available to completely disable JIT...


Anyway - let's get our hands dirty, shall we?


The easiest way to do it, would be to create your local overlay (unless you've already got one). Assuming that you don't here's what needs to be done. Choose a folder where you will store you local ebuild - say /usr/local/portage. Next create there required folder structure:

mkdir /usr/local/portage
mkdir -p /usr/local/portage/net-libs/xulrunner

Yes, we actually need to amend the xulrunner ebuild and not the firefox one.


Now we need to copy the "original" ebuild along with the patches which will serve as a baseline:

cp /usr/portage/net-libs/xulrunner/xulrunner-2.0.1-r1.ebuild /usr/local/portage/net-libs/xulrunner/
cp -r /usr/portage/net-libs/xulrunner/files/ /usr/local/portage/net-libs/xulrunner/

Now open the copied ebuild in your favourite editor and locate the following code:

mozconfig_annotate '' --with-default-mozilla-five-home="${MOZLIBDIR}"
mozconfig_annotate '' --enable-extensions="${MEXTENSIONS}"
mozconfig_annotate '' --disable-mailnews
mozconfig_annotate '' --enable-canvas
mozconfig_annotate '' --enable-safe-browsing
mozconfig_annotate '' --with-system-png
mozconfig_annotate '' --enable-system-ffi
mozconfig_use_enable system-sqlite
mozconfig_use_enable gconf

Add after the last mozconfig_annotate line the following code:

mozconfig_annotate '' --disable-jit
mozconfig_annotate '' --disable-methodjit

...so the whole chunk looks like this:

mozconfig_annotate '' --with-default-mozilla-five-home="${MOZLIBDIR}"
mozconfig_annotate '' --enable-extensions="${MEXTENSIONS}"
mozconfig_annotate '' --disable-mailnews
mozconfig_annotate '' --enable-canvas
mozconfig_annotate '' --enable-safe-browsing
mozconfig_annotate '' --with-system-png
mozconfig_annotate '' --enable-system-ffi
mozconfig_annotate '' --disable-jit
mozconfig_annotate '' --disable-methodjit
mozconfig_use_enable system-sqlite
mozconfig_use_enable gconf

Halfway through! Now, unfortunately that is not enough - we'll have to patch xulrunners source too...so here we go!


First, create folder where we can save our patch to be automatically picked up during compilation. It could be added explicitly to the ebuild but this way is just easier and less scary for some perhaps ;)

mkdir -p /etc/portage/patches/net-libs/xulrunner

...and save in that folder file (under whatever name) with the content below:

diff -Nurp ./mozilla-2.0/js/src/assembler/wtf/Platform.h
./mozilla-2.0.new/js/src/assembler/wtf/Platform.h
--- ./mozilla-2.0/js/src/assembler/wtf/Platform.h 2011-05-12
22:06:56.000000000 +0100
+++ ./mozilla-2.0.new/js/src/assembler/wtf/Platform.h 2011-05-12
22:12:35.000000000 +0100
@@ -918,15 +918,7 @@ on MinGW. See https://bugs.webkit.org/sh
 #if !defined(ENABLE_YARR_JIT)

 /* YARR supports x86 & x86-64, and has been tested on Mac and Windows. */
-#if (WTF_CPU_X86 \
- || WTF_CPU_X86_64 \
- || WTF_CPU_ARM_TRADITIONAL \
- || WTF_CPU_ARM_THUMB2 \
- || WTF_CPU_X86)
-#define ENABLE_YARR_JIT 1
-#else
 #define ENABLE_YARR_JIT 0
-#endif

 #endif /* !defined(ENABLE_YARR_JIT) */

Nearly there! Now, we need to create digest for our newly created ebuild,so:

# ebuild /usr/local/portage/net-libs/xulrunner/xulrunner-2.0.1-r1.ebuild digest
>>> Creating Manifest for /usr/local/portage/net-libs/xulrunner

...and tell portage to use our local ebuild:

echo PORTDIR_OVERLAY="/usr/local/portage" >> /etc/make.conf

Ready to compile! Emerging xulrunner should give you output similar to this:

# emerge -av xulrunner

These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild R ~] net-libs/xulrunner-2.0.1-r1 USE="alsa crashreporter dbus ipc webm wifi -custom-optimization -debug -gconf -libnotify -startup-notification -system-sqlite" 0 kB [0=>1]

Total: 1 package (1 reinstall), Size of downloads: 0 kB
Portage tree and overlays:
[0] /usr/portage
[1] /usr/local/portage

As can be seen, our new ebuild is just about to be emerged!


Make sure that you see the code being patched (I named the patch jit.patch)

...
* 5009_use_system_libffi.patch ... [ ok ]
* Done with patching
* Applying mozilla-2.0_support_64bit_big_endian.patch ... [ ok ]
* Applying user patches from /etc/portage/patches//net-libs/xulrunner ...
* jit.patch ... [ ok ]

* Done with patching
...

...and then when the summary of config options is displayed (seconds later), you will see this:

--with-system-png mozilla.org default
--enable-system-ffi mozilla.org default
--disable-jit mozilla.org default
--disable-methodjit mozilla.org default

--disable-system-sqlite -system-sqlite
--disable-gconf -gconf
==========================================================

Looks good! So after short while...perfect for a cup of coffee or a pint of your favourite lager, xulrunner is ready! Now we need to recompile firefox itself against it...

emerge firefox

The ebuild will still disable mprotect on Firefox as we haven't touched it. Just before we enable it using paxutils, we need to disable all the JIT options in Firefox itself. So start it up, type "about:config" in the address bar and hit enter. Don't be worry about loosing warranty ;) Type jit in the filter and disable any option that is set to 'true' (click twice on it to change its value). Close Firefox and we can enable mprotect now!

# paxctl -v /usr/lib/firefox/firefox
PaX control v0.5
Copyright 2004,2005,2006,2007 PaX Team

- PaX flags: -----m-x-e-- [/usr/lib/firefox/firefox]
MPROTECT is disabled
RANDEXEC is disabled
EMUTRAMP is disabled

But that's not what we want! So:

# paxctl -M /usr/lib/firefox/firefox
# paxctl -v /usr/lib/firefox/firefox
PaX control v0.5
Copyright 2004,2005,2006,2007 PaX Team

- PaX flags: ----M--x-e-- [/usr/lib/firefox/firefox]
MPROTECT is enabled
RANDEXEC is disabled
EMUTRAMP is disabled

Start Firefox and...voila - it works! :)

It is worth noting, that plugins now run in a separate process: plugin-container which is normally located in /usr/lib/xulrunner-2.0/. To achieve best security, it should have the mprotect flag enabled as well. (Un)fortunatelly - flash will not work! So if you don't care about youtube and alike:

paxctl -M /usr/lib64/xulrunner-2.0/plugin-container

To verify that it is actually working you can find the PID of firefox running the ps command and then cat /proc/PID/status and at the bottom there will be something like this:

Cpus_allowed: f
Cpus_allowed_list: 0-3
Mems_allowed: 00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 21023
nonvoluntary_ctxt_switches: 1664
PaX: PeMRs

...where the capital 'M' stands for enabled MPROTECT. How cool is that? ;) Enjoy!