about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Makeconfig8
-rw-r--r--csu/Makefile22
-rw-r--r--elf/Makefile4
3 files changed, 20 insertions, 14 deletions
diff --git a/Makeconfig b/Makeconfig
index 0a4811b5e5..01f8638c2e 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -856,6 +856,14 @@ ifneq ($(stack-protector),)
 +stack-protector=$(stack-protector)
 endif
 
+# Some routines are unsafe to build with stack-protection since they're called
+# before the stack check guard is set up.  Provide a way to disable stack
+# protector.  The first argument is the extension (.o, .os, .oS) and the second
+# is a list of routines that this path should be applied to.
+define elide-stack-protector
+$(if $(filter $(@F),$(patsubst %,%$(1),$(2))), $(no-stack-protector))
+endef
+
 # This is the program that generates makefile dependencies from C source files.
 # The -MP flag tells GCC >= 3.2 (which we now require) to produce dummy
 # targets for headers so that removed headers don't break the build.
diff --git a/csu/Makefile b/csu/Makefile
index e587434be8..3054329cea 100644
--- a/csu/Makefile
+++ b/csu/Makefile
@@ -45,18 +45,20 @@ install-lib = $(start-installed-name) g$(start-installed-name) $(csu-dummies)
 # code is compiled with special flags.
 tests =
 
-CFLAGS-.o += $(no-stack-protector)
-CFLAGS-.op += $(no-stack-protector)
-CFLAGS-.os += $(no-stack-protector)
-
-# Dummy object not actually used for anything.  It is linked into
-# crt1.o nevertheless, which in turn is statically linked into
+# static-reloc.os is a dummy object not actually used for anything.  It is
+# linked into crt1.o nevertheless, which in turn is statically linked into
 # applications, so that build flags matter.
 # See <https://sourceware.org/ml/libc-alpha/2018-07/msg00101.html>.
-# NB: Using $(stack-protector) in this way causes a wrong definition
-# STACK_PROTECTOR_LEVEL due to the preceding $(no-stack-protector),
-# but it does not matter for this source file.
-CFLAGS-static-reloc.os += $(stack-protector)
+#
+# libc-start.os is safe to be built with stack protector since
+# __libc_start_main is called after stack canary setup is done.
+ssp-safe.os = static-reloc libc-start
+
+CFLAGS-.o += $(call elide-stack-protector,.o,$(routines))
+CFLAGS-.op += $(call elide-stack-protector,.op,$(routines))
+CFLAGS-.oS += $(call elide-stack-protector,.oS,$(routines))
+CFLAGS-.os += $(call elide-stack-protector,.os,$(filter-out \
+						 $(ssp-safe.os),$(routines)))
 
 ifeq (yes,$(build-shared))
 extra-objs += S$(start-installed-name) gmon-start.os
diff --git a/elf/Makefile b/elf/Makefile
index ba4689a7fa..3b8e13e066 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -83,10 +83,6 @@ endif
 # Also compile all routines in the static library that are elided from
 # the shared libc because they are in libc.a in the same way.
 
-define elide-stack-protector
-$(if $(filter $(@F),$(patsubst %,%$(1),$(2))), $(no-stack-protector))
-endef
-
 CFLAGS-.o += $(call elide-stack-protector,.o,$(elide-routines.os))
 CFLAGS-.op += $(call elide-stack-protector,.op,$(elide-routines.os))
 CFLAGS-.os += $(call elide-stack-protector,.os,$(all-rtld-routines))