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!

1 comment:

  1. Does this just activate mprotect or does it actually make Firefox run?

    ReplyDelete

Have your say: