make;
make install;

some notes to myself

Blog

About

Build a grsec-patched kernel for Ubuntu 16.04

Written on September 4, 2016

This walk-through was forked from ageis’ gist on building a grsec-patched kernel for Debian 8 and DigitalOcean.

grsecurity is “an extensive security enhancement to the Linux kernel that defends against a wide range of security threats through intelligent access control, memory corruption-based exploit prevention, and a host of other system hardening”.

Note: The stable patches are not publicly available anymore, so we’ll be applying the free 4.7.2 (test) patch. The URLs and filenames in this document may become outdated, so fetch the latest from grsecurity.net and kernel.org.

Install dependencies:

sudo apt-get install build-essential fakeroot libncurses5-dev libssl-dev ccache gcc-5 gcc-5-plugin-dev make bc

Grab Spender’s key and verify it:

wget https://grsecurity.net/spender-gpg-key.asc
gpg --import spender-gpg-key.asc
gpg --keyserver pool.sks-keyservers.net --recv-key 647F28654894E3BD457199BE38DBBDC86092693E
gpg --with-fingerprint spender-gpg-key.asc
gpg --fingerprint 647F28654894E3BD457199BE38DBBDC86092693E

Grab the kernel source and grsecurity patch, plus signatures for each:

wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.7.2.tar.xz
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.7.2.tar.sign
wget https://grsecurity.net/test/grsecurity-3.1-4.7.2-201608312326.patch
wget https://grsecurity.net/test/grsecurity-3.1-4.7.2-201608312326.patch.sig

Decompress the tarball:

unxz linux-4.7.2.tar.xz

Verify that the signatures are good:

gpg --verify grsecurity-3.1-4.7.2-201608312326.patch.sig
gpg --verify linux-4.7.2.tar.sign

Extract the kernel source and apply the patch:

tar xf linux-4.7.2.tar
cd linux-4.7.2
patch -p1 < ../grsecurity-3.1-4.7.2-201608312326.patch

Start with the server’s existing kernel configuration, and then configure stuff:

cp /boot/config-4.4.0-36-generic .config
yes '' | make oldconfig
make menuconfig

Under Security options, enable Grsecurity (press Y), set Configuration Method to Automatic, set Usage Type to Server, set Virtualization Type to Guest, set Virtualization Software to KVM and Required Priorities to Security. Save and exit.

Now you can compile the kernel. It can take a while to finish, and ideally you shouldn’t be doing this as root.

make -j $(grep -c '^processor' /proc/cpuinfo)

Now install the kernel and modules, and generate the initramfs and new grub.cfg:

sudo make modules_install install

Install some tools to use with PaX (which hardens userland binaries against common exploitation techniques based on memory corruption):

apt-get install paxtest paxctl

Reboot with the new kernel

sudo reboot

When the machine comes back after rebooting, check uname -r to verify that you’re running grsec.

Set these sysctl variables (use sysctl -p to activate after editing /etc/sysctl.conf):

kernel.grsecurity.rwxmap_logging = 0
kernel.grsecurity.grsec_lock = 1

Set some PaX flags for GRUB:

sudo -- sh -c 'paxctl -Cpm /usr/sbin/grub-probe; paxctl -Cpm /usr/sbin/grub-mkdevicemap; paxctl -Cpm /usr/sbin/grub-install; paxctl -Cpm /usr/bin/grub-script-check; paxctl -Cpm /usr/bin/grub-mount'

You may find that some stuff won’t work like common interpreters for scripting languages because of memory protection. As an example, you can disable MPROTECT for Python like so:

paxctl -c /usr/bin/python2.7
paxctl -m /usr/bin/python2.7

Run paxtest blackhat and check the output. If PaX is working, you should see something like this:

Executable anonymous mapping             : Killed
Executable bss                           : Killed
Executable data                          : Killed
Executable heap                          : Killed
Executable stack                         : Killed
Executable shared library bss            : Killed
Executable shared library data           : Killed
Executable anonymous mapping (mprotect)  : Killed
Executable bss (mprotect)                : Killed
Executable data (mprotect)               : Killed
Executable heap (mprotect)               : Killed
Executable stack (mprotect)              : Killed
Executable shared library bss (mprotect) : Killed
Executable shared library data (mprotect): Killed
Writable text segments                   : Killed
Anonymous mapping randomisation test     : 28 bits (guessed)
Heap randomisation test (ET_EXEC)        : 23 bits (guessed)
Heap randomisation test (PIE)            : 35 bits (guessed)
Main executable randomisation (ET_EXEC)  : 28 bits (guessed)
Main executable randomisation (PIE)      : 28 bits (guessed)
Shared library randomisation test        : 28 bits (guessed)
Stack randomisation test (SEGMEXEC)      : 35 bits (guessed)
Stack randomisation test (PAGEEXEC)      : 35 bits (guessed)
Arg/env randomisation test (SEGMEXEC)    : 39 bits (guessed)
Arg/env randomisation test (PAGEEXEC)    : 39 bits (guessed)
Randomization under memory exhaustion @~0: 28 bits (guessed)
Randomization under memory exhaustion @0 : 28 bits (guessed)
Return to function (strcpy)              : paxtest: return address contains a NULL byte.
Return to function (memcpy)              : Killed
Return to function (strcpy, PIE)         : paxtest: return address contains a NULL byte.
Return to function (memcpy, PIE)         : Killed

Congratulations! You’re now running grsecurity.

See also paxctld, a daemon for applying PaX flags to bianries persistently across package updates. I also suggest evaluating the grsecurity RBAC (role-based access control), which is extremely powerful.

Special acknowledgments to Garrett Robinson, James Dolan, Runa Sandvik, and Conor Schaefer whose work on building kernels for SecureDrop informed this guide.