by David "Del" Elson
last updated February 28, 2002
This article will discuss the grsecurity patches available for the Linux kernel. Grsecurity is a suite of patches (distributed as a single patch file) for the Linux kernel that are an attempt to improve the security of a Linux system. Grsecurity is based on a port of some previous patches for the Linux 2.2 kernel, including Openwall and PaX, which have never been ported to the 2.4 kernel. Grsecurity provides some updates to these patches and has been ported to the Linux 2.4 kernel.
As of this writing, grsecurity is available as version 1.9.4 and is specific to the Linux 2.4.17 kernel. Grsecurity can be found and downloaded from its home page.
How Does It Work?
Grsecurity is not an additional security service that might be run periodically (such as Tripwire, AIDE or Logwatch), nor is it supplied as a loadable kernel module like the ipchains or iptables firewalling software. Grsecurity does its work by physically patching the Linux kernel to make processes more restricted.
There are good reasons to do this. For example, it is a common programming "mistake" to take data entered by the user during a program, store that data on the stack temporarily or inside an array without checking the array bounds, and then return some of it during a function call or object method. A malicious user can sometimes exploit this mistake by entering data (for example, on a program command line or via a network connection) that is larger than the program was expecting, thus causing a "stack overflow". This type of stack overflow can sometimes cause data on the stack to be executed accidentally as the function return essentially "crashes", which can in turn allow the attacker enhanced privileges on or root access to the machine.
Some of grsecurity's patches (specifically the ones taken from Openwall) are designed to stop this type of attack by making the stack non-executable. This might seem like a must-have feature, until we discover that there are a few programs (including some versions of GCC) that use the ability of the stack to contain executable code to perform an action called "trampolining", which can improve program efficiency in a few cases.
In addition to the stack protection mentioned above, grsecurity also includes some code from PaX, including a set of options for enabling processes to mark memory pages as non-executable. This is an extension of the Openwall theory that is used to prevent programs from running code that they had not intended to run.
Grsecurity also includes an ACL system, additional protection for kernel memory and the /proc filesystem, some protection against "fork bombs" (programs that continually run extra copies of themselves to deny services to other users of the system), and additional kernel auditing.
Grsecurity also borrows some concepts from LIDS (Linux Intrusion Detection System), although it does not implement many of the features of LIDS. In particular, prevention against file tampering is stronger in LIDS, although the ACL system in grsecurity definitely addresses the same issues in a different way.
In all of these cases it is a good idea to examine what the Grsecurity patches do and why before applying them to every system on the network.
What Do the Patches Alter?
Grsecurity contains a 300K patch file enabling many different features, many of which are quite independent. Each of these features operates like a mini-patch in itself, changing the operation of some part of the kernel. This article will briefly examine the patch that prevents kernel stack execution.
The patch affects a few files, including:
Looking at the patch in general, the parts of the code modified in arch/i386/kernel have to do with memory mapping of the stack itself. This makes it easier for the kernel to track these areas so that, on return, signal handlers (such as in signal.c and traps.c) can detect whether a buffer overflow into the stack may have taken place and a security alert can be raised. Similar stack detection code is placed into mmap.c.
The code changes to the binfmt_* files are to take into account certain file system flags, which are useful for identifying certain programs where trampolining may be expected.
These additions change the way that the kernel works internally, as they essentially force the kernel to do a little bit more checking on return value before passing it to a user space process, although any performance hit is very slight.
Obviously, all of these modifications to the kernel may interfere with modifications to the kernel made by the Linux vendor (eg: Red Hat, Debian, etc). Many of these vendors insert their own modifications into the kernel to allow larger memory spaces, include or update device drivers that were not in the default kernel, and provide other custom modifications. Generally speaking, grsecurity will only work on an unpatched, "clean" kernel, and not one supplied by a distribution vendor.
Of course, one of the advantages of prepackaged kernels is that they can be easier to update and don't require recompiling on the user’s machine. Generally, Linux vendors supply a kernel with most of the device drivers set up as loadable modules, and so a single generically-compiled kernel will suit nearly all users. The convenience of such a distribution must be weighed against the added protection of patch sets like grsecurity: applying grsecurity's patches across a wide network of many hundreds of machines may not be desirable, but using it to improve protection on a few critical devices might be prudent.
I have to confess to being somewhat nervous when installing patches such as grsecurity, Openwall, and LIDS in a networked environment. Generally speaking, I would not install such patches on my home desktop PC, as I frequently make many types of configuration changes to this machine, it is on a protected network away from the eyes of intruders (except those that have a key to my front door), and these patches generally involve some kind of performance penalty. Grsecurity and other patches of its type also tend to make life more difficult if the user has a machine that changes configuration on a regular basis.
On the other hand, grsecurity is ideal for a server or firewall exposed to the Internet or other insecure network. In the case of a public Web server, the advanced ACL system, the protection against stack overflows, the auditing, and additional enforcement of chroot jails are an excellent idea.
It must also be noted that grsecurity is merely one tool in a security administrator's toolkit. It should always be used in combination with other tools, such as a good firewall, some intrusion detection (network- and host-based), and regular system monitoring and application of security patches as soon as they become available.
Obtaining and Installing Grsecurity
To obtain the grsecurity patch, simply follow the "download" link on the home page, and download the 3 files listed there. The important file is the first one - grsecurity-1.9.4-2.4.17.patch, which is available directly via http://www.grsecurity.net/grsecurity-1.9.4-2.4.17.patch.
Remember that grsecurity is specific to one kernel version, and as of this writing that version is 2.4.17. If the you has a kernel source supplied by a vendor, such as RedHat's kernel-src RPM file, then you must not use grsecurity to patch that; instead you should obtain the original "unblemished" 2.4.17 kernel from http://www.kernel.org/ or a mirror. The kernel file you are looking for is linux-2.4.17.tar.gz (or the .bz2 file if you prefer).
To unpack the Linux kernel, simply follow the standard instructions:
cd /usr/src tar xfz (path)/linux-2.4.17.tar.gz
where (path) is the location you have downloaded the grsecuritypatch to.
To patch the linux kernel with the grsecurity patch, use the following command:
cd /usr/src patch -p0 < (path)/grsecurity-1.9.4-2.4.17.patch
You should receive a bunch of nice messages as follows:
patching file linux/Documentation/Configure.help patching file linux/Makefile patching file linux/arch/alpha/config.in patching file linux/arch/arm/config.in ... patching file linux/net/netsyms.c patching file linux/net/socket.c
You now have the task of configuring and building your Linux kernel with the installed grsecurity patches. There are several ways to do this, such as "make config", "make menuconfig" or "make xconfig" (if you have X installed). For the purposes of grsecurity I have used "make menuconfig".
During the configuration process, either at the bottom of the menu (if you are using menuconfig) or towards the end of the selection process, you will see a "grsecurity" option. Select this. There are a number of other sub options that will appear:
All of the grsecurity options and sub-options come with their own help page, which can be viewed by pressing the "?" key when selecting an option. Also, there is documentation of the grsecurity options at the grsecurity home page (specifically here) and so it becomes a matter of reading all of this documentation to determine the best set of options for your system.
As a sample system, grsecurity has been configured on an Internet-exposed Web server. It contains some internal firewalling using the iptables module, but is not behind a firewall. It has a number of user accounts, but the users do not have shell access. There are some daemons that run as root, and some that run as a restricted user account in a chroot jail. For this system, following options within grsecurity have been selected, and all of the rest have been turned off:
Buffer Overflow Protection:
Access Control Lists. Note that I have some need for ACLs but, because no users are logged onto this system using a shell, I have only enabled the basic ACL support:
Filesystem protections. I want to be fairly strict on chrooted processes here because I know that they shouldn't be interfering with the system in general and should be prevented from mounting filesystems, contacting other processes, etc.
Kernel auditing. Note that there are very few user processes here, and so there isn't a lot I need in this area. I have enabled a few things to be logged to catch happenings that are out of the ordinary:
Executable protections. Nothing selected in this area. On a system with more user shell accounts I might be tempted to select several of the options, including Exec process limiting and randomized PIDs.
Network protections. These provide some level of confusion to a cracker that might be scanning the system.
Sysctl support. This isn't something I'm likely to need on a system that remains mostly static, although I have enabled it for the purposes of this article. Whether you use it or not is up to you.
Compiling the Kernel
The kernel is now compiled using the standard commands:
make dep make clean make make modules make modules_install mkinitrd /boot/initrd-2.4.17-grsec-1.9.4.img 2.4.17-grsec-1.9.4 make install
You should now have a kernel (vmlinuz) in /boot. Depending on your boot loader, you should now edit your grub.conf or lilo.conf file, and re-run lilo if appropriate.
You should make sure that both the grsecurity-enhanced kernel and your previous kernel are available, in case you need to reboot from the previous kernel you had installed. Incorrect configuration information given during make menuconfig can cause the kernel to be non-bootable. My first few attempts to get the ACL system in grsecurity working caused a kernel panic in init, so if this happens to you, don't get too distressed.
Along with the grsecurity patch, there is a program called gradm which will be required if ACL support is required. Obtain this program, and compile it using the following commands:
tar xfz gradm-1.2.tar.gz cd gradm-1.2 ./configure make make install
Note that the location of the gradm binary is in /sbin, this location is compiled into the kernel and so you need to take care if you are changing it. Installing gradm will require you to enter a password, which is stored in /etc/grsec/pw in an encrypted format.
You should also look at the gradm ACL system documentation, located on the grsecurity download site. This gives some examples of the configuration files that need to go into /etc/grsec to get ACLs working.
Once you have installed grsecurity and gradm, it is now time to reboot your system to use the new kernel.
If you have not enabled grsecurity's sysctl support, then grsecurity is very much "on" all of the time. If you are using sysctl support then most of grsecurity's features can be turned on or off by using the files in /proc/sys/net/kernel/grsecurity.
Turning features on involves echoing the value "1" to one of the files in /proc/sys/kernel/grsecurity. You would normally do this in a system startup script, for example /etc/rc.d/rc.local.
You can continue to turn features on (or off by echoing the value "0") until you set the "grsec_lock" entry, by echoing "1" to the file /proc/sys/kernel/grsecurity/grsec_lock. Once that is done, the configuration is locked in place and cannot be changed except by a reboot.
Using the "gradm" program
The following command enables grsecurity's ACL features:
The following command disables grsecurity's ACL features:
Note that you will need to enter the gradm password to disable the ACLs. Generally speaking, you should enable the ACL system on bootup (eg: in /etc/rc.d/rc.local) and leave it running the entire time. If you need to over-ride the ACL system for a short while, you can use "gradm -a".
The thing that I really don't like about grsecurity's ACL system is that the ACL information is stored in a pair of system files. However, until ACL support becomes widespread through, say, the ext2 / ext3 file system, this is one of the things that people who need ACLs on Linux will be stuck with for a while.
The fact that ACLs aren't stored in the file system essentially makes them static, and so it limits what you might use the ACLs for. They are best used to protect system files from modification or use, while allowing certain processes special rights to access them.
How you would structure your ACL files to achieve that is probably a whole new article!
Grsecurity is a good method to improve the security on an exposed Linux system. It can assist with file system and process protection, and provides ports of several 2.2 kernel enhancements to the 2.4 kernel. The ACL system is limited but could be of some use on a system where many users have shell accounts or similar access. Restrictions imposed on chroot jailed processes can help improve the security of daemons such as BIND or cgi-bin scripts which it might be desirable to run chroot'ed.
Getting grsecurity set up correctly, with the correct options enabled in the kernel can be somewhat tricky. Examine what your system is being used for, and read through the comments attached to each configuration option carefully to determine whether it suits your needs.
Grsecurity contains a grab bag of patches, and there's something inside for many system administrators; however, its reliance on a single version of the Linux kernel and the way that it patches certain files may limit its interoperability with vendor-supplied patches or other patch sets such as FreeS/WAN. Discussions on the FreeS/WAN mailing list have indicated that this may be the case.
This article originally appeared on SecurityFocus.com -- reproduction in whole or in part is not allowed without expressed written consent.