Support for building an hardened OpenWRT

Introduce configuration options to build an "hardened" OpenWRT.

Options to enable Stack-Smashing Protection, FORTIFY_SOURCE and RELRO
have been introduced.

uClibc makefile now automatically detects if SSP support is necessary.

hostapd makefile has been fixed to use "^" as sed separator since
using a comma was problematic when using "-Wl,-z,now" and the like in
TARGET_CFLAGS.

Currently enabling SSP on user space depends on enabling SSP kernel
side, this is due to the fact that TARGET_CFLAGS are used to build
kernel modules (at least). Suggestions on how to avoid this are welcome.
Using "select" instead of "depends on" doesn't seem to work with choice
entries.

Tested with a lantiq (WBMR) router, GCC 4.8, uClibc and a subset of
the available packages.
Needs to be tested with GCC 4.9 and the remaining packages.
PIE not currently included.

Signed-off-by: Alessandro Di Federico <ale+owrt@clearmind.me>

SVN-Revision: 44005
This commit is contained in:
John Crispin 2015-01-17 14:31:30 +00:00
parent 64ccdb98fb
commit 491f3fc048
4 changed files with 117 additions and 10 deletions

View File

@ -97,15 +97,6 @@ menu "Global build settings"
If you are unsure, select N. If you are unsure, select N.
config PKG_CHECK_FORMAT_SECURITY
bool
prompt "Enable gcc format-security"
default n
help
Add -Wformat -Werror=format-security to the CFLAGS. You can disable
this per package by adding PKG_CHECK_FORMAT_SECURITY:=0 in the package
Makefile.
config PKG_BUILD_USE_JOBSERVER config PKG_BUILD_USE_JOBSERVER
bool bool
prompt "Use top-level make jobserver for packages" prompt "Use top-level make jobserver for packages"
@ -216,4 +207,83 @@ menu "Global build settings"
bool "libstdc++" bool "libstdc++"
endchoice endchoice
comment "Hardening build options"
config PKG_CHECK_FORMAT_SECURITY
bool
prompt "Enable gcc format-security"
default n
help
Add -Wformat -Werror=format-security to the CFLAGS. You can disable
this per package by adding PKG_CHECK_FORMAT_SECURITY:=0 in the package
Makefile.
choice
prompt "User space Stack-Smashing Protection"
default PKG_CC_STACKPROTECTOR_NONE
help
Enable GCC Stack Smashing Protection (SSP) for userspace applications
config PKG_CC_STACKPROTECTOR_NONE
bool "None"
config PKG_CC_STACKPROTECTOR_REGULAR
bool "Regular"
select SSP_SUPPORT
depends on KERNEL_CC_STACKPROTECTOR_REGULAR
config PKG_CC_STACKPROTECTOR_STRONG
bool "Strong"
select SSP_SUPPORT
depends on GCC_VERSION_4_9_LINARO
depends on KERNEL_CC_STACKPROTECTOR_STRONG
endchoice
choice
prompt "Kernel space Stack-Smashing Protection"
default KERNEL_CC_STACKPROTECTOR_NONE
help
Enable GCC Stack-Smashing Protection (SSP) for the kernel
config KERNEL_CC_STACKPROTECTOR_NONE
bool "None"
config KERNEL_CC_STACKPROTECTOR_REGULAR
bool "Regular"
config KERNEL_CC_STACKPROTECTOR_STRONG
depends on GCC_VERSION_4_9_LINARO
bool "Strong"
endchoice
choice
prompt "Enable buffer-overflows detction (FORTIFY_SOURCE)"
help
Enable the _FORTIFY_SOURCE macro which introduces additional
checks to detect buffer-overflows in the following standard library
functions: memcpy, mempcpy, memmove, memset, strcpy, stpcpy,
strncpy, strcat, strncat, sprintf, vsprintf, snprintf, vsnprintf,
gets. "Conservative" (_FORTIFY_SOURCE set to 1) only introduces
checks that sholdn't change the behavior of conforming programs,
while "aggressive" (_FORTIFY_SOURCES set to 2) some more checking is
added, but some conforming programs might fail.
config PKG_FORTIFY_SOURCE_NONE
bool "None"
config PKG_FORTIFY_SOURCE_1
bool "Conservative"
config PKG_FORTIFY_SOURCE_2
bool "Aggressive"
endchoice
choice
prompt "Enable RELRO protection"
help
Enable a link-time protection know as RELRO (Relocation Read Only)
which helps to protect from certain type of exploitation techniques
altering the content of some ELF sections. "Partial" RELRO makes the
.dynamic section not writeable after initialization, introducing
almost no performance penalty, while "full" RELRO also marks the GOT
as read-only at the cost of initializing all of it at startup.
config PKG_RELRO_NONE
bool "None"
config PKG_RELRO_PARTIAL
bool "Partial"
config PKG_RELRO_FULL
bool "Full"
endchoice
endmenu endmenu

View File

@ -15,6 +15,12 @@ PKG_MD5SUM ?= unknown
PKG_BUILD_PARALLEL ?= PKG_BUILD_PARALLEL ?=
PKG_USE_MIPS16 ?= 1 PKG_USE_MIPS16 ?= 1
PKG_CHECK_FORMAT_SECURITY ?= 1 PKG_CHECK_FORMAT_SECURITY ?= 1
PKG_CC_STACKPROTECTOR_REGULAR ?= 1
PKG_CC_STACKPROTECTOR_STRONG ?= 1
PKG_FORTIFY_SOURCE_1 ?= 1
PKG_FORTIFY_SOURCE_2 ?= 1
PKG_RELRO_PARTIAL ?= 1
PKG_RELRO_FULL ?= 1
ifneq ($(CONFIG_PKG_BUILD_USE_JOBSERVER),) ifneq ($(CONFIG_PKG_BUILD_USE_JOBSERVER),)
MAKE_J:=$(if $(MAKE_JOBSERVER),$(MAKE_JOBSERVER) -j) MAKE_J:=$(if $(MAKE_JOBSERVER),$(MAKE_JOBSERVER) -j)
@ -39,6 +45,36 @@ ifdef CONFIG_PKG_CHECK_FORMAT_SECURITY
TARGET_CFLAGS += -Wformat -Werror=format-security TARGET_CFLAGS += -Wformat -Werror=format-security
endif endif
endif endif
ifdef CONFIG_PKG_CC_STACKPROTECTOR_REGULAR
ifeq ($(strip $(PKG_CC_STACKPROTECTOR_REGULAR)),1)
TARGET_CFLAGS += -fstack-protector
endif
endif
ifdef CONFIG_PKG_CC_STACKPROTECTOR_STRONG
ifeq ($(strip $(PKG_CC_STACKPROTECTOR_STRONG)),1)
TARGET_CFLAGS += -fstack-protector-strong
endif
endif
ifdef CONFIG_PKG_FORTIFY_SOURCE_1
ifeq ($(strip $(PKG_FORTIFY_SOURCE_1)),1)
TARGET_CFLAGS += -D_FORTIFY_SOURCE=1
endif
endif
ifdef CONFIG_PKG_FORTIFY_SOURCE_2
ifeq ($(strip $(PKG_FORTIFY_SOURCE_2)),1)
TARGET_CFLAGS += -D_FORTIFY_SOURCE=2
endif
endif
ifdef CONFIG_PKG_RELRO_PARTIAL
ifeq ($(strip $(PKG_RELRO_PARTIAL)),1)
TARGET_CFLAGS += -Wl,-z,relro
endif
endif
ifdef CONFIG_PKG_RELRO_FULL
ifeq ($(strip $(PKG_RELRO_FULL)),1)
TARGET_CFLAGS += -Wl,-z,now -Wl,-z,relro
endif
endif
include $(INCLUDE_DIR)/prereq.mk include $(INCLUDE_DIR)/prereq.mk
include $(INCLUDE_DIR)/host.mk include $(INCLUDE_DIR)/host.mk

View File

@ -294,7 +294,7 @@ define Build/Compile/wpad
echo ` \ echo ` \
$(call Build/RunMake,hostapd,-s MULTICALL=1 dump_cflags); \ $(call Build/RunMake,hostapd,-s MULTICALL=1 dump_cflags); \
$(call Build/RunMake,wpa_supplicant,-s MULTICALL=1 dump_cflags) | \ $(call Build/RunMake,wpa_supplicant,-s MULTICALL=1 dump_cflags) | \
sed -e 's,-n ,,g' -e 's,$(TARGET_CFLAGS),,' \ sed -e 's,-n ,,g' -e 's^$(TARGET_CFLAGS)^^' \
` > $(PKG_BUILD_DIR)/.cflags ` > $(PKG_BUILD_DIR)/.cflags
+$(call Build/RunMake,hostapd, \ +$(call Build/RunMake,hostapd, \
CFLAGS="$$$$(cat $(PKG_BUILD_DIR)/.cflags)" \ CFLAGS="$$$$(cat $(PKG_BUILD_DIR)/.cflags)" \

View File

@ -80,6 +80,7 @@ define Host/Configure
-e 's,^.*UCLIBC_HAS_SHADOW.*,UCLIBC_HAS_SHADOW=$(if $(CONFIG_SHADOW_PASSWORDS),y,n),g' \ -e 's,^.*UCLIBC_HAS_SHADOW.*,UCLIBC_HAS_SHADOW=$(if $(CONFIG_SHADOW_PASSWORDS),y,n),g' \
-e 's,^.*UCLIBC_HAS_LOCALE.*,UCLIBC_HAS_LOCALE=$(if $(CONFIG_BUILD_NLS),y,n),g' \ -e 's,^.*UCLIBC_HAS_LOCALE.*,UCLIBC_HAS_LOCALE=$(if $(CONFIG_BUILD_NLS),y,n),g' \
-e 's,^.*UCLIBC_BUILD_ALL_LOCALE.*,UCLIBC_BUILD_ALL_LOCALE=$(if $(CONFIG_BUILD_NLS),y,n),g' \ -e 's,^.*UCLIBC_BUILD_ALL_LOCALE.*,UCLIBC_BUILD_ALL_LOCALE=$(if $(CONFIG_BUILD_NLS),y,n),g' \
-e 's,^.*UCLIBC_HAS_SSP.*,UCLIBC_HAS_SSP=$(if $(or $(CONFIG_PKG_CC_STACKPROTECTOR_REGULAR),$(CONFIG_PKG_CC_STACKPROTECTOR_STRONG)),y,n),g' \
$(HOST_BUILD_DIR)/.config.new $(HOST_BUILD_DIR)/.config.new
cmp -s $(HOST_BUILD_DIR)/.config.new $(HOST_BUILD_DIR)/.config.last || { \ cmp -s $(HOST_BUILD_DIR)/.config.new $(HOST_BUILD_DIR)/.config.last || { \
cp $(HOST_BUILD_DIR)/.config.new $(HOST_BUILD_DIR)/.config && \ cp $(HOST_BUILD_DIR)/.config.new $(HOST_BUILD_DIR)/.config && \