Compiling grsec kernel for Fedora 20

31 March 2014


There is a lot of information online on how to roll your own kernel with the grsecurity patch. This is especially true for Gentoo or Debian. But to apply grsec to Fedora, there are some unexpected issues you might come across. The purpose of this post is to understand the classic merging problems and how to address them.

Disclaimer: By the time you read this post, the version numbers will be obsolete. There should be enough comments for you to adapt this method to any current version.


First, let's install the necessary tools to build RPMS:

# yum install rpmdevtools yum-utils gcc-plugin-devel
$ rpmdev-setuptree

The last command will create a rpmbuild directory in your $HOME. If you'd rather use another path, you can put %_topdir %{getenv:HOME}/my_path in ~/.rpmmacros.

Then, we retrieve the current kernel SRPM, locally install it and install the building dependencies:

$ yumdownloader --source kernel
$ rpm -Uvh kernel-3.13.7-200.fc20.src.rpm
# yum-builddep kernel

Get the test patch from grsecurity and put it into the SOURCES directory:

$ wget

and verify its signature (If it's your first time, you will have to import the signing key first):

$ gpg --verify grsecurity-3.0-3.13.7-201403281902.patch.sig 
gpg: Signature made Sat 29 Mar 2014 10:11:54 EST using RSA key ID 2525FE49
gpg: Good signature from "Bradley Spengler (spender) <>"

Now, let's add the grsec patch into our configuration. In the SPECS directory, modify kernel.spec. Change:

# % define buildid .local


%define buildid .grsec




Patch26000: grsecurity-3.0-3.13.7-201403281902.patch




ApplyPatch grsecurity-3.0-3.13.7-201403281902.patch

Let's test the patching. The "bp" flag of rpmbuild is used to decompress and patch the sources:

$ rpmbuild -bp kernel.spec
Patch26000: grsecurity-3.0-3.13.7-201403281902.patch
+ case "$patch" in
+ patch -p1 -F1 -s
2 out of 4 hunks FAILED -- saving rejects to file arch/x86/kernel/ioport.c.rej
1 out of 1 hunk FAILED -- saving rejects to file arch/x86/vdso/Makefile.rej
1 out of 1 hunk FAILED -- saving rejects to file drivers/acpi/custom_method.c.rej
3 out of 3 hunks FAILED -- saving rejects to file drivers/platform/x86/asus-wmi.c.rej
1 out of 3 hunks FAILED -- saving rejects to file init/Kconfig.rej
Reversed (or previously applied) patch detected!  Assume -R? [n]

Failing at that point is completely normal. There are usually two types of failure: a patch is included inside both Fedora's default kernel and grsecurity or some functionalities are in conflict. To solve both, it is easy to find which patches is making the modification. In the SOURCES directory, use a grep on the file that failed merging, for instance:

$ grep -Rin ioport\.c .
./ --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
./ a/arch/x86/kernel/ioport.c
./ b/arch/x86/kernel/ioport.c
./grsecurity-3.0-3.13.7-201403281902.patch:24823:diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
./grsecurity-3.0-3.13.7-201403281902.patch:24825:--- a/arch/x86/kernel/ioport.c
./grsecurity-3.0-3.13.7-201403281902.patch:24826:+++ b/arch/x86/kernel/ioport.c
./secure-modules.patch:198: arch/x86/kernel/ioport.c | 5 +++--
./secure-modules.patch:202:diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
./secure-modules.patch:204:--- a/arch/x86/kernel/ioport.c
./secure-modules.patch:205:+++ b/arch/x86/kernel/ioport.c

In this case we will remove the series of patches from Fedora regarding the UEFI Secure Boot. In kernel.spec, comment out:

# secure boot
#Patch1000: secure-modules.patch
#Patch1001: modsign-uefi.patch
#Patch1002: sb-hibernate.patch
#Patch1003: sysrq-secure-boot.patch


# secure boot
#ApplyPatch secure-modules.patch
#ApplyPatch modsign-uefi.patch
#ApplyPatch sb-hibernate.patch
#ApplyPatch sysrq-secure-boot.patch

Using the same procedure, you can comment out all the following patch which are already included in grsecurity:

#Patch25026: keyring-fix.patch
#Patch25031: net-fix-for-a-race-condition-in-the-inet-frag-code.patch
#Patch25041: ipv6-dont-set-DST_NOCOUNT-for-remotely-added-routes.patch
#Patch25045: netfilter-nf_conntrack_dccp-fix-skb_header_pointer-A.patch

#ApplyPatch keyring-fix.patch
#ApplyPatch net-fix-for-a-race-condition-in-the-inet-frag-code.patch
#ApplyPatch ipv6-dont-set-DST_NOCOUNT-for-remotely-added-routes.patch
#ApplyPatch netfilter-nf_conntrack_dccp-fix-skb_header_pointer-A.patch

Now some patches from Fedora may add more functionalities than grsecurity. For instance, to solve the vdso/Makefile error, it is easier to remove the grsec part (which adds compilation error in case some symbols are not resolved):

diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile
index fd14be1..e3c79c0 100644
--- a/arch/x86/vdso/Makefile
+++ b/arch/x86/vdso/Makefile
@@ -181,7 +181,7 @@ quiet_cmd_vdso = VDSO    $@
           -Wl,-T,$(filter,$^) $(filter %.o,$^) && \
     sh $(srctree)/$(src)/ '$(NM)' '$@'

-VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
+VDSO_LDFLAGS = -fPIC -shared -Wl,--no-undefined $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)


The same applies for init/Kconfig, remove "if EXPERT" in the grsec patch:

diff --git a/init/Kconfig b/init/Kconfig
index 4e5d96a..93cd8a1 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1079,6 +1079,7 @@ endif # CGROUPS

  bool "Checkpoint/restore support" if EXPERT
+ depends on !GRKERNSEC
  default n
    Enables additional kernel features in a sake of checkpoint/restore.

By default, grsecurity patch also add a "-grsec" suffix to the kernel. This is already handled by the Fedora spec, so we can safely remove that:

diff --git a/localversion-grsec b/localversion-grsec
new file mode 100644
index 0000000..7cd6065
--- /dev/null
+++ b/localversion-grsec
@@ -0,0 +1 @@

If you run again the rpmbuild command the patching should now be successful. And the following error is now reached:

+ cat .newoptions
+ exit 1
error: Bad exit status from /var/tmp/rpm-tmp.H6mU7j (%prep)

This means that you haven't configured the grsec options for your kernel. At this stage you should go to the BUILD directory and run a make (config|menuconfig|xconfig). Once you have made your selection, copy all the CONFIG_GRKERNSEC and CONFIG_PAX options into the file SOURCES/config-local. For instance, here is my config-local (Desktop + KVM Host).

By default, the kernel.spec will try to configure the kernel for every architecture, which causes some issues with your configuration. To avoid that, modify SPECS/kernel.spec:

# now run oldconfig over all the config files
for i in *.config


for i in *x86_64.config

Let's try to compile:

$ rpmbuild -bb --without debug --without debuginfo --without extra --without perf --without tools kernel.spec

We now reach the following compilation error:

drivers/input/serio/i8042.c:677:13: error: i8042_irq_being_tested causes a section type conflict with dmi_system_table
static bool i8042_irq_being_tested __initdata;

Back to kernel.spec to comment out these patches:

#Patch12016: disable-i8042-check-on-apple-mac.patch
#ApplyPatch disable-i8042-check-on-apple-mac.patch

And here is our final build:

$ rpmbuild -bb --without debug --without debuginfo --without extra --without perf --without tools kernel.spec

Time to install the generated kernel:

$ cd ~/rpmbuild/RPMS/x86_64
$ sudo yum install kernel-3.13.7-200.grsec.fc20.x86_64.rpm