[fedora-arm] SELinux problem fix

Jon Masters jcm at redhat.com
Tue Nov 20 08:10:15 UTC 2012


Hi Folks,

A previous configuration change to the Fedora kernel configs altered the
value of the minimum mmap address mapping value from 32768 to 65536 (the
value that is the inherited default from x86_64). Unfortunately, on ARM
systems, we begin mapping executables at the lower address.

Fedora systems use SELinux, an LSM (Linux Security Module) written by
NSA (see security/selinux and in particular security/selinux/hooks.c for
the gory details). SELinux includes various avc permissions checks that
are performed to see if a task in a given context has the ability to
perform specific tasks, such as to mmap a memory region. mmap is the
process by which an executable (or other memory) is mapped into a
process's (called a task within the kernel) address space as a new
virtual memory area (vma). During the loading of a modern ELF binary
(see load_elf_binary) various ELF headers will determine the load
locations of specific parts of the executable, calling (ultimately) for
an mmap of specific pieces of the binary at certain addresses. In the
end, on SELinux systems, this results in a call to selinux_mmap_addr:

static int selinux_mmap_addr(unsigned long addr)
{
        int rc = 0;
        u32 sid = current_sid();

        /*
         * notice that we are intentionally putting the SELinux check
         * before the secondary cap_file_mmap check.  This is such a
         * likely attempt at bad behaviour/exploit that we always want
         * to get the AVC, even if DAC would have also denied the
         * operation.
         */
        if (addr < CONFIG_LSM_MMAP_MIN_ADDR) {
                rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT,
                                  MEMPROTECT__MMAP_ZERO, NULL);
                if (rc)
                        return rc;
        }

        /* do DAC check on address space usage */
        return cap_mmap_addr(addr);
}

As you can see from the above code, we will specifically check to see
the load address is lower than the minimal mmap_min_addr that we have
defined. This is to (generally) prevent tasks from being able to map the
"zero page". The zero page (literally address zero) is special because
it contains address 0x0 or NULL. If we can map the NULL pointer (zero)
then we may be able to possibly take advantage of various NULL pointer
exploits to cause the kernel (or other privileged code we later exec,
etc.) to execute malicious code. Because this is such a well known
attack vector that has been abused many times in the past, this specific
check has been introduced, and in general we deny software from mapping
at this address (with specific exceptions, such as WINE on x86_64, which
has its own special rules to allow Windows emulation).

In the end, a simple problem. Unfortunately, systemd renders debugging
of modern Unix systems during early bootup extremely difficult (and
there will be many more situations in the future that are undebuggable
when these problems arise). The situation was compounded by the fact
that I went down a couple of the wrong rabbit holes before looking for
the most obvious solution. That'll teach me. Patch attached. Scratch
build is running now:

http://arm.koji.fedoraproject.org/koji/taskinfo?taskID=1257217

I know I'm sometimes very busy, but I am in general very happy to help
review kernel configuration changes. Please reach out to me and ask if
in doubt about making a change. Some of these are very fiddly and ARM
specific and require a lot of detailed understanding before changing.

Jon.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: fedora-arm-fix-mmap_min_addr.patch
Type: text/x-patch
Size: 1686 bytes
Desc: not available
URL: <http://lists.fedoraproject.org/pipermail/arm/attachments/20121120/5b5de6cb/attachment.bin>


More information about the arm mailing list