From e38b74ba89d3d03e01ee751131d2a6dc316ac33a Mon Sep 17 00:00:00 2001
From: Joachim Fasting <joachifm@fastmail.fm>
Date: Fri, 18 Nov 2016 15:04:39 +0100
Subject: [PATCH] grsecurity: work around for #20490

In `scripts/Makefile.modinst`, the code that generates the list of
modules to install passes file names via the command line.  When
installing a grsecurity kernel, this list appears to exceed the
shell's argument list limit, as in

    make[2]: execvp: /nix/store/[...]-bash-4.3-p46/bin/bash: Argument list too long

The build does not fail, however, but the list of modules to be installed ends
up being empty.  Thus, the resulting kernel package output contains no modules,
rendering it useless.

We work around this by patching the makefile to use `find -exec` to
process files.  Why this would occur for grsecurity and not other
kernels is unknown, most likely there's something *else* that is
actually causing this behaviour, so this is a temporary fix until that
cause is found.

Fixes https://github.com/NixOS/nixpkgs/issues/20490
---
 .../linux/kernel/grsecurity-modinst.patch            | 12 ++++++++++++
 pkgs/os-specific/linux/kernel/patches.nix            |  8 ++++++++
 pkgs/top-level/all-packages.nix                      |  2 +-
 3 files changed, 21 insertions(+), 1 deletion(-)
 create mode 100644 pkgs/os-specific/linux/kernel/grsecurity-modinst.patch

diff --git a/pkgs/os-specific/linux/kernel/grsecurity-modinst.patch b/pkgs/os-specific/linux/kernel/grsecurity-modinst.patch
new file mode 100644
index 000000000000..275d96fbb29b
--- /dev/null
+++ b/pkgs/os-specific/linux/kernel/grsecurity-modinst.patch
@@ -0,0 +1,12 @@
+diff -ruN a/scripts/Makefile.modinst b/scripts/Makefile.modinst
+--- a/scripts/Makefile.modinst	2016-11-15 07:49:06.000000000 +0100
++++ b/scripts/Makefile.modinst	2016-11-18 13:45:07.977270500 +0100
+@@ -9,7 +9,7 @@
+ 
+ #
+ 
+-__modules := $(sort $(shell grep -h '\.ko$$' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
++__modules := $(shell find $(MODVERDIR) -name '*.mod' -exec grep -h '\.ko$$' '{}' \; | sort)
+ modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o)))
+ 
+ PHONY += $(modules)
diff --git a/pkgs/os-specific/linux/kernel/patches.nix b/pkgs/os-specific/linux/kernel/patches.nix
index 3c6058c407a5..db1ce8c38013 100644
--- a/pkgs/os-specific/linux/kernel/patches.nix
+++ b/pkgs/os-specific/linux/kernel/patches.nix
@@ -99,6 +99,14 @@ rec {
       patch = ./grsecurity-nixos-kmod.patch;
     };
 
+  # A temporary work-around for execvp: arglist too long error during
+  # module_install.  Without this, no modules are installed into the
+  # resulting output.
+  grsecurity_modinst =
+    { name = "grsecurity-modinst";
+      patch = ./grsecurity-modinst.patch;
+    };
+
   crc_regression =
     { name = "crc-backport-regression";
       patch = ./crc-regression.patch;
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 135f6f850a2e..186fa10a6aff 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -11154,7 +11154,7 @@ in
         ];
     };
     grsecPatch = self.kernelPatches.grsecurity_testing;
-    kernelPatches = [ self.kernelPatches.grsecurity_nixos_kmod ];
+    kernelPatches = with self.kernelPatches; [ grsecurity_nixos_kmod grsecurity_modinst ];
     extraConfig = callPackage ../os-specific/linux/kernel/grsecurity-nixos-config.nix { };
   };