PaX Flag migration from PT_PAX to XATTR_PAX
Before you start reading!
This page is a quick howto on migrating from PT_PAX to XATTR_PAX flags.
It presupposes the reader knows what PaX is all about. See our
Pax Quickstart for a broad coverage.
For an in-depth explanation of how PaX works, see the
Homepage of The PaX Team.
The three ways of marking PaX flags: EI_PAX, PT_PAX and XATTR_PAX
PaX provides various protections against abuses of memory. Some of
these protections can only be enabled or disabled by (re)configuring the
kernel and recompiling/rebooting. However a few important ones (PAGEEXEC,
EMUTRAMP, MPROTECT, RANDMMAP and SEGMEXEC) can be tweaked when the
system is up and running by marking the PaX flags on the ELF objects of
the program you want to run. Since some programs need to use memory in
a way normally forbidden by PaX, we may have to relax some restrictions
on a per program basis.
Historically, the PaX flags have been stored in one of three different
locations. At first, they were housed in the ELF header of the objects
(EI_PAX), but this broke with updates to glibc. They were next moved to
an ELF program header (PT_PAX) and this was mostly satisfactory, except
for those occassion programs where adding such a header was problematic
for one reason or another. The next generation places the flags in the
extended attributes of the filesystem(s). As long as all the filesystems
and the utilities working with those files/filesystems respects the extended
attributes, this is the best solution because it essentially does not touch
the ELF binaries themselves.
Migrating from PT_PAX to XATTR_PAX
Marking the ELF header (EI_PAX) has been completely deprecated in Gentoo.
If you have an ancient system which still uses EI_PAX, then its probably
so broken by this point that no migration is possible anyhow. Start over.
Marking the ELF program header (PT_PAX) is still supported, but that support
will slowly disappear. As of glibc-2.16, the elf.h header file will
no longer contain the definitions of the PT_PAX_FLAGS program header, nor of the
values of the PaX flags that live there (
bug #440018). At some point in the future, the patch against binutils which
includes the PT_PAX_FLAGS program header will also go. At that point only XATTR_FLAGS
will remain. You might want to get ahead of the game and migrate now.
The process of migration is safe because at no point will we actually dump
the PT_PAX flags, so we can always revert if something goes wrong. The essential
caveat to remember is that the kernel ultimately decides whether to use PT_PAX
or XATTR_PAX (or both). So you can have both markings on an ELF object and
have the kernel read one and ignore the other. Note that if you enable both
PT_PAX and XATTR_PAX in the kernel, and you create an XATTR_PAX field, then
the kernel expects both fields to be identical, otherwise neither is respected. It
is okay to enable both fields provided you don't create XATTR_PAX; then, the
PT_PAX field is fully respected. We can use this as part of the migration; but in
general, we do not recommend setting both unless there is a good reason. Just
switch from one to the other, ie PT_PAX xor XATTR_PAX.
So, starting from a stock PT_PAX system, you can migrate to XATTR_PAX as follows:
- 1. Userland preliminaries:
- First, let's make sure that your userland utilities can handle extended
attributes in general and XATTR_PAX in particular. If they cannot, then either
the XATTR_PAX markings will fail or they'll get lost as we pack/unpack our ELF
objects, for example, when using tar. So,
a. make sure you set USE=xattr in your global USE flags, and
b. emerge >=sys-apps/elfix-0.8.1 without disabling either ptpax or xtpax USE flags.
- 2. Portage preliminaries:
- The current in tree pax-utils.eclass is not XATTR_PAX aware, and so we need to
use the pax-utils.eclass from the
hardened-development overlay. Add the overlay using layman and make sure you
set up your repos.conf file so that it overrides the tree eclass (man portage for more
details on how to setup repos.conf). This step will be removed once we update the eclass
in tree (bug #431092).
- 3. Kernel preliminaries:
- As you do the migration, you must make sure your filesystem can accomodate extended
attributes, including tmpfs! If your kernel hasn't been already so configured, do so
now and reboot into it. Choosing PAX_XATTR_PAX_FLAGS under the PaX kernel menu
will automatically set extended attributes on as many filesystems as can support them.
Remember, you can enable both PT_PAX and XATTR_PAX in the kernel at this point, and
PT_PAX will be respected until you create XATTR_PAX fields on the target binaries.
We'll tolerate this as a transition, but we recommend using only XATTR_PAX afterward.
- 4. Migrate the flags:
- The elfix package comes with migrate-pax. Running it with the -m flag will
copy the PT_PAX flags to XATTR_PAX for every ELF object that portage knows about,
except for those object which have the default flags. Since a kernel
configured to use only XATTR_PAX will fall back on the default flags when no XATTR_PAX
field is found, there is no reason to create such a field when the default flags are
desired. Running migrate-pax -m is very safe and you can easily undo it by
running migrate-pax -d.
- 5. Boot into an XATTR_PAX only kernel:
- You can now boot into a pure XATTR_PAX kernel. Make sure PT_PAX is off. Even
though the flags should be the same in both fields, or XATTR_PAX absent in the case
of default flags, we will be on the side of caution and keep control over the effective
flags by using only XATTR_PAX.
- 6. Profit!
- If you really want to make sure it worked, the elfix package comes with some test
suites. These are tricky to use correctly because if you have the wrong combination
of PT_PAX versus XATTR_PAX userland/kernel configurations, you'll get a lot of false
failures. The next section shows you how to test.
Testing whether the migration worked and XATTR_PAX flags are respected
So did the migration work? And is the kernel recognizing XATTR_PAX markings? You can
verify that the migration worked by spot checking with paxctl-ng. Try something
like the following:
Code Listing 4.1: Spot checking migration with paxctl-ng
# paxctl-ng -v /bin/*
ELF ERROR: elf_kind() fail: this is not an elf file. <--- This is not really an ELF object, expect failure
PT_PAX : not found
XATTR_PAX: not found
/bin/vdir: <--- Good! No XATTR_PAX flags means we get the default
PT_PAX : -e--- <--- Only 'e' (don't emulate trampolines) is the default setting.
XATTR_PAX: not found
/bin/ypdomainname: <--- Good! Both PT_PAX and XATTR_PAX are identical
PT_PAX : -em--
# paxctl-ng -v /lib/*
/lib/libz.so.1.2.7: <--- Even libraries should have matching flags (here its the default)
PT_PAX : -e---
XATTR_PAX: not found
open(O_RDWR) failed: cannot change PT_PAX flags <--- This is a directory, expect failure
ELF ERROR: elf_begin() fail: (null)
PT_PAX : not found
XATTR_PAX: not found
To check if the kernel is recognizing XATTR_PAX markings, we'll use a test suite from
the sys-apps/elfix package. We'll have to checkout the git repo since the ebuild doesn't
run tests. They are tricky and can give lots of false negatives if you don't have the
right combination of PT_PAX versus XATTR_PAX in both userland and kernel. You can proceed
Code Listing 4.2: Using elfix test suite to see if XATTR_PAX is working
# git clone git://git.overlays.gentoo.org/proj/elfix.git
# cd elfix
# ./configure --disable-ptpax --enable-xtpax --enable-tests
# cd tests/pxtpax/
RUNNIG DAEMON TEST
1) This test is only for amd64 and i686
2) This test will fail on amd64 unless the following are enabled in the kernel:
3) This test will fail on i686 unless the following are enabled in the kernel:
Mismatches = 0
No mismatches! It worked. What the test is doing is marking a daemon with
every possible combination of PaX flags, starting it, checking if its running
with the expected flags, and reporting. If you want to have fun with this, try
enabling PT_PAX and disabling XATTR_PAX when you configure elfix, but keep only
XATTR_PAX support in the kernel. It will fail miserably as no PaX flags are
The contents of this document, unless otherwise expressly stated, are licensed under the CC-BY-SA-2.5 license. The Gentoo Name and Logo Usage Guidelines apply.