From 38d51f9a00939c48f09cae12e37a733645230766 Mon Sep 17 00:00:00 2001
From: auREAX <mark@xn--hwg34fba.ws>
Date: Thu, 4 Oct 2012 03:46:32 +0200
Subject: [PATCH] Add GRSecurity compatibility with --enable-pax-marks
 configure flag; add GRSecurity autodetection code to configure.

---
 configure    | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 mk/stage0.mk |  4 ++++
 mk/target.mk |  4 ++++
 3 files changed, 63 insertions(+)

diff --git a/configure b/configure
index 9f3ecddefe13f..07e22bed8d6d0 100755
--- a/configure
+++ b/configure
@@ -295,6 +295,7 @@ opt manage-submodules 1 "let the build manage the git submodules"
 opt mingw-cross 0 "cross-compile for win32 using mingw"
 opt clang 0 "prefer clang to gcc for building the runtime"
 opt local-rust 0 "use an installed rustc rather than downloading a snapshot"
+opt pax-marks 0 "apply PaX markings to rustc binaries (required for GRSecurity/PaX-patched kernels)"
 valopt prefix "/usr/local" "set installation prefix"
 valopt local-rust-root "/usr/local" "set prefix for local rust binary"
 valopt llvm-root "" "set LLVM root"
@@ -343,6 +344,8 @@ probe CFG_PDFLATEX         pdflatex
 probe CFG_XETEX            xetex
 probe CFG_LUATEX           luatex
 probe CFG_NODE             nodejs node
+probe CFG_PAXCTL           paxctl /sbin/paxctl
+probe CFG_ZCAT             zcat
 
 if [ ! -z "$CFG_PANDOC" ]
 then
@@ -354,6 +357,52 @@ then
     fi
 fi
 
+if [ "$CFG_OSTYPE" = "unknown-linux-gnu" ]
+then
+    if [ ! -z "$CFG_ENABLE_PAX_MARKS" -a -z "$CFG_PAXCTL" ]
+    then
+        err "enabled PaX markings but no paxctl binary found"
+    fi
+
+    if [ -z "$CFG_DISABLE_PAX_MARKS" ]
+    then
+        # GRSecurity/PaX detection. This can be very flaky.
+        GRSEC_DETECTED=
+
+        # /dev/grsec only exists if CONFIG_GRKERNSEC_NO_RBAC is not set.
+        # /proc is normally only available to root and users in the CONFIG_GRKERNSEC_PROC_GID group,
+        # and /proc/sys/kernel/grsecurity is not available if ÇONFIG_GRKERNSEC_SYSCTL is not set.
+        if [ -e /dev/grsec -o -d /proc/sys/kernel/grsecurity ]
+        then
+            GRSEC_DETECTED=1
+        # /proc/config.gz is normally only available to root, and only if CONFIG_IKCONFIG_PROC has been set.
+        elif [ -r /proc/config.gz -a ! -z "$CFG_ZCAT" ]
+        then
+            if "$CFG_ZCAT" /proc/config.gz | grep --quiet "CONFIG_GRKERNSEC=y"
+            then
+                GRSEC_DETECTED=1
+            fi
+        # Flaky.
+        elif grep --quiet grsec /proc/version
+        then
+            GRSEC_DETECTED=1
+        fi
+
+        if [ ! -z "$GRSEC_DETECTED" ]
+        then
+            step_msg "GRSecurity: yes"
+            if [ ! -z "$CFG_PAXCTL" ]
+            then
+                CFG_ENABLE_PAX_MARKS=1
+            else
+                warn "GRSecurity kernel detected but no paxctl binary found: not setting CFG_ENABLE_PAX_MARKS"
+            fi
+        else
+            step_msg "GRSecurity: no"
+        fi
+    fi
+fi
+
 if [ ! -z "$CFG_ENABLE_LOCAL_RUST" ]
 then
     if [ ! -f ${CFG_LOCAL_RUST_ROOT}/bin/rustc ]
@@ -699,6 +748,12 @@ putvar CFG_C_COMPILER
 putvar CFG_LIBDIR
 putvar CFG_DISABLE_MANAGE_SUBMODULES
 
+if [ ! -z "$CFG_ENABLE_PAX_MARKS" ]
+then
+    putvar CFG_ENABLE_PAX_MARKS
+    putvar CFG_PAXCTL
+fi
+
 if [ ! -z $BAD_PANDOC ]
 then
     CFG_PANDOC=
diff --git a/mk/stage0.mk b/mk/stage0.mk
index e55b9f70c8ff0..fae6b3742f815 100644
--- a/mk/stage0.mk
+++ b/mk/stage0.mk
@@ -12,6 +12,10 @@ ifdef CFG_ENABLE_LOCAL_RUST
 	$(Q)$(S)src/etc/local_stage0.sh $(CFG_HOST_TRIPLE) $(CFG_LOCAL_RUST_ROOT)
 else 
 	$(Q)$(S)src/etc/get-snapshot.py $(CFG_HOST_TRIPLE) $(SNAPSHOT_FILE)
+ifdef CFG_ENABLE_PAX_MARKS
+	@$(call E, apply PaX markings: $@)
+	@"$(CFG_PAXCTL)" -cm "$@"
+endif
 endif 
 	$(Q)touch $@
 
diff --git a/mk/target.mk b/mk/target.mk
index 5ddc825d335bd..458d2a4ac63bf 100644
--- a/mk/target.mk
+++ b/mk/target.mk
@@ -29,6 +29,10 @@ $$(TBIN$(1)_T_$(2)_H_$(3))/rustc$$(X):				\
 		$$(TLIBRUSTC_DEFAULT$(1)_T_$(2)_H_$(3))
 	@$$(call E, compile_and_link: $$@)
 	$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$<
+ifdef CFG_ENABLE_PAX_MARKS
+	@$$(call E, apply PaX markings: $$@)
+	@"$(CFG_PAXCTL)" -cm "$$@"
+endif
 
 $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC):		\
 		$$(COMPILER_CRATE) $$(COMPILER_INPUTS)		\