Skip to contentSkip to conversation

stack protector: moved option out of adv menu

PATCH Superseded Matt Weber 4 participants 10 messages Oct 25, 2017 – Nov 11, 2017

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

Matt Weber

author
#0 lore raw

PATCH v2 1/2 stack protector: moved option out of adv menu

---
Changes
v1 -> v2
[Arnout
- Move to a comment breaking up the options vs submenu

---
 Config.in | 112 ++++++++++++++++++++++++++++++++------------------------------
 1 file changed, 57 insertions(+), 55 deletions(-)
Config.in +57 -55
index 814dc02..61f6aa6 100644
@@ -566,61 +566,6 @@ config BR2_GOOGLE_BREAKPAD_INCLUDE_FILES
 endif
 
 choice
-	bool "build code with Stack Smashing Protection"
-	default BR2_SSP_ALL if BR2_ENABLE_SSP # legacy
-	depends on BR2_TOOLCHAIN_HAS_SSP
-	help
-	  Enable stack smashing protection support using GCC's
-	  -fstack-protector option family.
-
-	  See
-	  http://www.linuxfromscratch.org/hints/downloads/files/ssp.txt
-	  for details.
-
-	  Note that this requires the toolchain to have SSP support.
-	  This is always the case for glibc and eglibc toolchain, but is
-	  optional in uClibc toolchains.
-
-config BR2_SSP_NONE
-	bool "None"
-	help
-	  Disable stack-smashing protection.
-
-config BR2_SSP_REGULAR
-	bool "-fstack-protector"
-	help
-	  Emit extra code to check for buffer overflows, such as stack
-	  smashing attacks. This is done by adding a guard variable to
-	  functions with vulnerable objects. This includes functions
-	  that call alloca, and functions with buffers larger than 8
-	  bytes. The guards are initialized when a function is entered
-	  and then checked when the function exits. If a guard check
-	  fails, an error message is printed and the program exits.
-
-config BR2_SSP_STRONG
-	bool "-fstack-protector-strong"
-	depends on BR2_TOOLCHAIN_GCC_AT_LEAST_4_9
-	help
-	  Like -fstack-protector but includes additional functions to be
-	  protected - those that have local array definitions, or have
-	  references to local frame addresses.
-
-comment "Stack Smashing Protection strong needs a toolchain w/ gcc >= 4.9"
-	depends on !BR2_TOOLCHAIN_GCC_AT_LEAST_4_9
-
-config BR2_SSP_ALL
-	bool "-fstack-protector-all"
-	help
-	  Like -fstack-protector except that all functions are
-	  protected. This option might have a significant performance
-	  impact on the compiled binaries.
-
-endchoice
-
-comment "Stack Smashing Protection needs a toolchain w/ SSP"
-	depends on !BR2_TOOLCHAIN_HAS_SSP
-
-choice
 	bool "libraries"
 	default BR2_SHARED_LIBS if BR2_BINFMT_SUPPORTS_SHARED
 	default BR2_STATIC_LIBS if !BR2_BINFMT_SUPPORTS_SHARED
@@ -728,6 +673,63 @@ config BR2_REPRODUCIBLE
 
 endmenu
 
+comment "Security Hardening Options"
+
+choice
+	bool "Stack Smashing Protection"
+	default BR2_SSP_ALL if BR2_ENABLE_SSP # legacy
+	depends on BR2_TOOLCHAIN_HAS_SSP
+	help
+	  Enable stack smashing protection support using GCC's
+	  -fstack-protector option family.
+
+	  See
+	  http://www.linuxfromscratch.org/hints/downloads/files/ssp.txt
+	  for details.
+
+	  Note that this requires the toolchain to have SSP support.
+	  This is always the case for glibc and eglibc toolchain, but is
+	  optional in uClibc toolchains.
+
+config BR2_SSP_NONE
+	bool "None"
+	help
+	  Disable stack-smashing protection.
+
+config BR2_SSP_REGULAR
+	bool "-fstack-protector"
+	help
+	  Emit extra code to check for buffer overflows, such as stack
+	  smashing attacks. This is done by adding a guard variable to
+	  functions with vulnerable objects. This includes functions
+	  that call alloca, and functions with buffers larger than 8
+	  bytes. The guards are initialized when a function is entered
+	  and then checked when the function exits. If a guard check
+	  fails, an error message is printed and the program exits.
+
+config BR2_SSP_STRONG
+	bool "-fstack-protector-strong"
+	depends on BR2_TOOLCHAIN_GCC_AT_LEAST_4_9
+	help
+	  Like -fstack-protector but includes additional functions to be
+	  protected - those that have local array definitions, or have
+	  references to local frame addresses.
+
+comment "Stack Smashing Protection strong needs a toolchain w/ gcc >= 4.9"
+	depends on !BR2_TOOLCHAIN_GCC_AT_LEAST_4_9
+
+config BR2_SSP_ALL
+	bool "-fstack-protector-all"
+	help
+	  Like -fstack-protector except that all functions are
+	  protected. This option might have a significant performance
+	  impact on the compiled binaries.
+
+endchoice
+
+comment "Stack Smashing Protection needs a toolchain w/ SSP"
+	depends on !BR2_TOOLCHAIN_HAS_SSP
+
 endmenu
 
 source "toolchain/Config.in"
Signature · 1 line
1.9.1
author
#1 lore raw

PATCH v2 2/2 security hardening: add RELFO, FORTIFY options

This enables a user to build a complete system using these options. It is important to note that not all packages will build correctly to start with. Additional initial patches which update linker ordering changes, etc will be upstreamed and then submitted to buildroot as a patch or bump.

A good testing tool to check a target's elf files for compliance to an array of hardening techniques can be found here:
https://github.com/slimm609/checksec.sh

---
Changes
v1 -> v2
- Cosmetic caps on titles

---
 Config.in           | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 package/Makefile.in | 25 +++++++++++++++++++++++
 2 files changed, 83 insertions(+)
Config.in +58 -0
index 61f6aa6..68eff24 100644
@@ -730,6 +730,64 @@ endchoice
 comment "Stack Smashing Protection needs a toolchain w/ SSP"
 	depends on !BR2_TOOLCHAIN_HAS_SSP
 
+choice
+	bool "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.
+
+config BR2_RELRO_NONE
+	bool "None"
+	help
+	  Enables Relocation link-time protections.
+
+config BR2_RELRO_PARTIAL
+	bool "Partial"
+	help
+	  This option makes the dynamic section not writeable after
+	  initialization (with almost no performance penalty).
+
+config BR2_RELRO_FULL
+	bool "Full"
+	help
+	  This option includes the partial configuration, but also
+	  marks the GOT as read-only at the cost of initialization time
+	  during program loading, i.e every time an executable is started.
+
+endchoice
+
+choice
+	bool "Buffer-overflow Detection (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.
+
+config BR2_FORTIFY_SOURCE_NONE
+	bool "None"
+	help
+	  Enables additional checks to detect buffer-overflows.
+
+config BR2_FORTIFY_SOURCE_1
+	bool "Conservative"
+	help
+	  This option sets _FORTIFY_SOURCE set to 1 and only introduces
+	  checks that shouldn't change the behavior of conforming programs.
+	  Adds checks at compile-time only.
+
+config BR2_FORTIFY_SOURCE_2
+	bool "Aggressive"
+	help
+	  This option sets _FORTIFY_SOURCES set to 2 and some more checking
+	  is added, but some conforming programs might fail.
+	  Also adds checks at run-time (detected buffer overflow terminates
+	  the program)
+
+endchoice
+
 endmenu
 
 source "toolchain/Config.in"
package/Makefile.in +25 -0
index a1a5316..c99361f 100644
@@ -144,6 +144,9 @@ TARGET_CXXFLAGS = $(TARGET_CFLAGS)
 TARGET_FCFLAGS = $(TARGET_ABI) $(TARGET_OPTIMIZATION) $(TARGET_DEBUGGING)
 TARGET_LDFLAGS = $(call qstrip,$(BR2_TARGET_LDFLAGS))
 
+TARGET_CFLAGS_RELRO = -Wl,-z,relro
+TARGET_CFLAGS_RELRO_FULL = -Wl,-z,now $(TARGET_CFLAGS_RELRO)
+
 ifeq ($(BR2_BINFMT_FLAT),y)
 TARGET_CFLAGS += $(if $($(PKG)_FLAT_STACKSIZE),-Wl$(comma)-elf2flt=-s$($(PKG)_FLAT_STACKSIZE),\
 	-Wl$(comma)-elf2flt)
@@ -181,6 +184,28 @@ TARGET_CXXFLAGS += -fstack-protector-all
 TARGET_FCFLAGS += -fstack-protector-all
 endif
 
+ifeq ($(BR2_RELRO_PARTIAL),y)
+TARGET_CFLAGS += $(TARGET_CFLAGS_RELRO)
+TARGET_CXXFLAGS += $(TARGET_CFLAGS_RELRO)
+TARGET_FCFLAGS += $(TARGET_CFLAGS_RELRO)
+TARGET_LDFLAGS += $(TARGET_CFLAGS_RELRO)
+else ifeq ($(BR2_RELRO_FULL),y)
+TARGET_CFLAGS += -fPIE $(TARGET_CFLAGS_RELRO_FULL)
+TARGET_CXXFLAGS += -fPIE $(TARGET_CFLAGS_RELRO_FULL)
+TARGET_FCFLAGS += -fPIE $(TARGET_CFLAGS_RELRO_FULL)
+TARGET_LDFLAGS += -pie
+endif
+
+ifeq ($(BR2_FORTIFY_SOURCE_1),y)
+TARGET_CFLAGS += -D_FORTIFY_SOURCE=1
+TARGET_CXXFLAGS += -D_FORTIFY_SOURCE=1
+TARGET_FCFLAGS += -D_FORTIFY_SOURCE=1
+else ifeq ($(BR2_FORTIFY_SOURCE_2),y)
+TARGET_CFLAGS += -D_FORTIFY_SOURCE=2
+TARGET_CXXFLAGS += -D_FORTIFY_SOURCE=2
+TARGET_FCFLAGS += -D_FORTIFY_SOURCE=2
+endif
+
 ifeq ($(BR2_TOOLCHAIN_BUILDROOT),y)
 TARGET_CROSS = $(HOST_DIR)/bin/$(GNU_TARGET_NAME)-
 else
Signature · 1 line
1.9.1
#2 lore raw

PATCH v2 2/2 security hardening: add RELFO, FORTIFY options

Hi Matt,

In the subject: s/RELFO/RELRO/

Quoted 3 lines · Matt Weber

This enables a user to build a complete system using these options. It is important to note that not all packages will build correctly to start with.

So perhaps you could make another patch that extends the autobuilders to test
this option. Just modify utils/genrandconfig and in the gen_config function randomly enable these options.

Quoted 40 lines

Additional initial patches
which update linker ordering changes, etc will be upstreamed and then submitted to buildroot as a patch or bump.

A good testing tool to check a target's elf files for compliance to an array of hardening techniques can be found here:
https://github.com/slimm609/checksec.sh

---
Changes
v1 -> v2
- Cosmetic caps on titles

---
 Config.in           | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 package/Makefile.in | 25 +++++++++++++++++++++++
 2 files changed, 83 insertions(+)
Config.in +14 -0
index 61f6aa6..68eff24 100644
@@ -730,6 +730,64 @@ endchoice
 comment "Stack Smashing Protection needs a toolchain w/ SSP"
 	depends on !BR2_TOOLCHAIN_HAS_SSP
 
+choice
+	bool "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.
+
+config BR2_RELRO_NONE
+	bool "None"
+	help
+	  Enables Relocation link-time protections.
+
+config BR2_RELRO_PARTIAL
+	bool "Partial"

Config.in endchoice · line 756

Quoted 10 lines
Config.in +10 -0
+	help
+	  This option makes the dynamic section not writeable after
+	  initialization (with almost no performance penalty).
+
+config BR2_RELRO_FULL
+	bool "Full"
+	help
+	  This option includes the partial configuration, but also
+	  marks the GOT as read-only at the cost of initialization time
+	  during program loading, i.e every time an executable is started.

Do these options make sense at all in static linking? Isn't it implicit then
(text is always readonly I think)? -pie is certainly invalid in static linking (at least with uClibc).

Also, does it make sense on NOMMU, even shared? I mean, "readonly" doesn't mean
much when there is no MMU I think...

Quoted 21 lines
Config.in +21 -0
+
+endchoice
+
+choice
+	bool "Buffer-overflow Detection (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.
+
+config BR2_FORTIFY_SOURCE_NONE
+	bool "None"
+	help
+	  Enables additional checks to detect buffer-overflows.
+
+config BR2_FORTIFY_SOURCE_1
+	bool "Conservative"
+	help
+	  This option sets _FORTIFY_SOURCE set to 1 and only introduces

Config.in endchoice · line 787

Quoted 10 lines
Config.in +10 -0
+	  checks that shouldn't change the behavior of conforming programs.
+	  Adds checks at compile-time only.
+
+config BR2_FORTIFY_SOURCE_2
+	bool "Aggressive"
+	help
+	  This option sets _FORTIFY_SOURCES set to 2 and some more checking
+	  is added, but some conforming programs might fail.
+	  Also adds checks at run-time (detected buffer overflow terminates
+	  the program)

Do you know how these behave in uClibc and musl? Waldemar, any idea? Obviously
the gcc part will still be activated, which covers about half of the functionality.

Quoted 21 lines
Config.in +3 -0
+
+endchoice
+
 endmenu
 
 source "toolchain/Config.in"
package/Makefile.in +3 -0
index a1a5316..c99361f 100644
@@ -144,6 +144,9 @@ TARGET_CXXFLAGS = $(TARGET_CFLAGS)
 TARGET_FCFLAGS = $(TARGET_ABI) $(TARGET_OPTIMIZATION) $(TARGET_DEBUGGING)
 TARGET_LDFLAGS = $(call qstrip,$(BR2_TARGET_LDFLAGS))
 
+TARGET_CFLAGS_RELRO = -Wl,-z,relro
+TARGET_CFLAGS_RELRO_FULL = -Wl,-z,now $(TARGET_CFLAGS_RELRO)
+
 ifeq ($(BR2_BINFMT_FLAT),y)
 TARGET_CFLAGS += $(if $($(PKG)_FLAT_STACKSIZE),-Wl$(comma)-elf2flt=-s$($(PKG)_FLAT_STACKSIZE),\
 	-Wl$(comma)-elf2flt)

package/Makefile.in TARGET_CXXFLAGS += -fstack-protector-all · line 190

Quoted 7 lines
package/Makefile.in +4 -0
@@ -181,6 +184,28 @@ TARGET_CXXFLAGS += -fstack-protector-all
 TARGET_FCFLAGS += -fstack-protector-all
 endif
 
+ifeq ($(BR2_RELRO_PARTIAL),y)
+TARGET_CFLAGS += $(TARGET_CFLAGS_RELRO)
+TARGET_CXXFLAGS += $(TARGET_CFLAGS_RELRO)
+TARGET_FCFLAGS += $(TARGET_CFLAGS_RELRO)

Since these are linker flags, it _should_ be sufficient to add them to LDFLAGS.
There may be some packages that don't listen to LDFLAGS so in that sense it could be a good idea to add it to CFLAGS as well, but I tend to prefer to fix the packages. Only, there is no easy way to detect that LDFLAGS are ignored.

package/Makefile.in TARGET_CXXFLAGS += -fstack-protector-all · line 201

Quoted 11 lines
package/Makefile.in +11 -0
+TARGET_LDFLAGS += $(TARGET_CFLAGS_RELRO)
+else ifeq ($(BR2_RELRO_FULL),y)
+TARGET_CFLAGS += -fPIE $(TARGET_CFLAGS_RELRO_FULL)
+TARGET_CXXFLAGS += -fPIE $(TARGET_CFLAGS_RELRO_FULL)
+TARGET_FCFLAGS += -fPIE $(TARGET_CFLAGS_RELRO_FULL)
+TARGET_LDFLAGS += -pie
+endif
+
+ifeq ($(BR2_FORTIFY_SOURCE_1),y)
+TARGET_CFLAGS += -D_FORTIFY_SOURCE=1
+TARGET_CXXFLAGS += -D_FORTIFY_SOURCE=1

It should go into CPPFLAGS (which automatically goes into CFLAGS and CXXFLAGS).

package/Makefile.in TARGET_CXXFLAGS += -fstack-protector-all · line 202

Quoted 1 line
package/Makefile.in +1 -0
+TARGET_FCFLAGS += -D_FORTIFY_SOURCE=1

FCFLAGS indeed needs to be handled separately. Except: is FORTIFY valid/useful
for Fortran?

Regards,
Arnout

Quoted 10 lines
package/Makefile.in +6 -0
+else ifeq ($(BR2_FORTIFY_SOURCE_2),y)
+TARGET_CFLAGS += -D_FORTIFY_SOURCE=2
+TARGET_CXXFLAGS += -D_FORTIFY_SOURCE=2
+TARGET_FCFLAGS += -D_FORTIFY_SOURCE=2
+endif
+
 ifeq ($(BR2_TOOLCHAIN_BUILDROOT),y)
 TARGET_CROSS = $(HOST_DIR)/bin/$(GNU_TARGET_NAME)-
 else
Signature · 6 lines
Arnout Vandecappelle                          arnout at mind be
Senior Embedded Software Architect            +32-16-286500
Essensium/Mind                                http://www.mind.be
G.Geenslaan 9, 3001 Leuven, Belgium           BE 872 984 063 RPR Leuven
LinkedIn profile: http://www.linkedin.com/in/arnoutvandecappelle
GPG fingerprint:  7493 020B C7E3 8618 8DEC 222C 82EB F404 F9AC 0DDF
#3 lore raw

PATCH v2 2/2 security hardening: add RELFO, FORTIFY options

Arnout,

Quoted 10 lines · Arnout Vandecappelle

Hi Matt,

In the subject: s/RELFO/RELRO/

Quoted 3 lines · Matt Weber

This enables a user to build a complete system using these options. It is important to note that not all packages will build correctly to start with.

So perhaps you could make another patch that extends the autobuilders to

test

Quoted 1 line

this option. Just modify utils/genrandconfig and in the gen_config

function

Quoted 1 line

randomly enable these options.

Sure :) I've got an initial patchset of half dozen packages we've fixed but I'm working upstreaming on some of them first before submitting here.

Another thing to note.... As things still build with various hardening flags possibly taking affect our not, we validated the configurations took affect by using the checksec.sh tool against all target binaries post-
build then went through fixing packages. I've been thinking about how to
do this checking..... I think at a minimum, I should add the test tool to this series and at least one buildroot test case to cover a static set of packages we've fixed so far. The other option would be a more active check post build that validates all target elfs are compliant.

Quoted 9 lines

Config.in endchoice · line 756

Quoted 7 lines
Config.in +7 -0
+
+config BR2_RELRO_FULL
+ bool "Full"
+ help
+ This option includes the partial configuration, but also
+ marks the GOT as read-only at the cost of initialization time
+ during program loading, i.e every time an executable is started.

Do these options make sense at all in static linking? Isn't it implicit

then

Quoted 1 line

(text is always readonly I think)? -pie is certainly invalid in static

linking

Quoted 3 lines

(at least with uClibc).

Also, does it make sense on NOMMU, even shared? I mean, "readonly"

doesn't mean

Quoted 2 lines

much when there is no MMU I think...

For both of those, I agree it doesn't make sense for static or NOMMU but I have asked my developer just to be sure.

Quoted 25 lines
Quoted 25 lines
Config.in +25 -0
+
+endchoice
+
+choice
+ bool "Buffer-overflow Detection (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.
+
+config BR2_FORTIFY_SOURCE_NONE
+ bool "None"
+ help
+ Enables additional checks to detect buffer-overflows.
+
+config BR2_FORTIFY_SOURCE_1
+ bool "Conservative"
+ help
+ This option sets _FORTIFY_SOURCE set to 1 and only introduces
+ checks that shouldn't change the behavior of conforming programs.
+ Adds checks at compile-time only.
+
+config BR2_FORTIFY_SOURCE_2
Quoted 8 lines
Quoted 6 lines

+ bool "Aggressive"
+ help
+ This option sets _FORTIFY_SOURCES set to 2 and some more checking
+ is added, but some conforming programs might fail.
+ Also adds checks at run-time (detected buffer overflow terminates
+ the program)

Do you know how these behave in uClibc and musl? Waldemar, any idea?

Obviously

Quoted 1 line

the gcc part will still be activated, which covers about half of the

functionality.

Quoted 1 line

Checking on the answer, but we ran through the complete test-pkg build list. I'll see which were skipped. We didn't see specific failures.

Quoted 14 lines
Quoted 14 lines
Config.in +3 -0
+
+endchoice
+

endmenu

source "toolchain/Config.in"

package/Makefile.in +0 -0
index a1a5316..c99361f 100644
@@ -144,6 +144,9 @@ TARGET_CXXFLAGS = $(TARGET_CFLAGS)
 TARGET_FCFLAGS = $(TARGET_ABI) $(TARGET_OPTIMIZATION) $(TARGET_DEBUGGING)
 TARGET_LDFLAGS = $(call qstrip,$(BR2_TARGET_LDFLAGS))
 
Quoted 5 lines
Quoted 5 lines
package/Makefile.in +3 -0
+TARGET_CFLAGS_RELRO = -Wl,-z,relro
+TARGET_CFLAGS_RELRO_FULL = -Wl,-z,now $(TARGET_CFLAGS_RELRO)
+
 ifeq ($(BR2_BINFMT_FLAT),y)

TARGET_CFLAGS += $(if

$($(PKG)_FLAT_STACKSIZE),-Wl$(comma)-elf2flt=-s$($(PKG)_FLAT_STACKSIZE),\

Quoted 11 lines

package/Makefile.in TARGET_CXXFLAGS += -fstack-protector-all · line 190

Quoted 9 lines
package/Makefile.in +0 -1
-Wl$(comma)-elf2flt)
@@ -181,6 +184,28 @@ TARGET_CXXFLAGS += -fstack-protector-all

TARGET_FCFLAGS += -fstack-protector-all
endif

package/Makefile.in +4 -0
+ifeq ($(BR2_RELRO_PARTIAL),y)
+TARGET_CFLAGS += $(TARGET_CFLAGS_RELRO)
+TARGET_CXXFLAGS += $(TARGET_CFLAGS_RELRO)
+TARGET_FCFLAGS += $(TARGET_CFLAGS_RELRO)

Since these are linker flags, it _should_ be sufficient to add them to

LDFLAGS.

Quoted 1 line

There may be some packages that don't listen to LDFLAGS so in that sense

it

Quoted 1 line

could be a good idea to add it to CFLAGS as well, but I tend to prefer to

fix

Quoted 1 line

the packages. Only, there is no easy way to detect that LDFLAGS are

ignored.

What we ended up with here worked for a large test build ( lots of packages in a glibc embedded router configuration) and passed a minimal test-pkg
cfg. That being said, we could go back and try flag combos but I know a
few of them can't be in the linker vs just cflags (and vice versa).

Quoted 14 lines

package/Makefile.in TARGET_CXXFLAGS += -fstack-protector-all · line 201

Quoted 12 lines
package/Makefile.in +11 -0
+TARGET_LDFLAGS += $(TARGET_CFLAGS_RELRO)
+else ifeq ($(BR2_RELRO_FULL),y)
+TARGET_CFLAGS += -fPIE $(TARGET_CFLAGS_RELRO_FULL)
+TARGET_CXXFLAGS += -fPIE $(TARGET_CFLAGS_RELRO_FULL)
+TARGET_FCFLAGS += -fPIE $(TARGET_CFLAGS_RELRO_FULL)
+TARGET_LDFLAGS += -pie
+endif
+
+ifeq ($(BR2_FORTIFY_SOURCE_1),y)
+TARGET_CFLAGS += -D_FORTIFY_SOURCE=1
+TARGET_CXXFLAGS += -D_FORTIFY_SOURCE=1

It should go into CPPFLAGS (which automatically goes into CFLAGS and

CXXFLAGS).

Nice that cleans it up

Quoted 4 lines
Quoted 2 lines

+TARGET_FCFLAGS += -D_FORTIFY_SOURCE=1

FCFLAGS indeed needs to be handled separately. Except: is FORTIFY

valid/useful

Quoted 2 lines

for Fortran?

It is not, shoot we got that feedback on the RFC. I'll remove it this time.

Matt
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.busybox.net/pipermail/buildroot/attachments/20171106/424998ec/attachment.html>

#4 lore raw

PATCH v2 2/2 security hardening: add RELFO, FORTIFY options

Arnout,

Quoted 93 lines · Matthew Weber

Arnout,

Quoted 9 lines · Arnout Vandecappelle

Hi Matt,

In the subject: s/RELFO/RELRO/

Quoted 3 lines · Matt Weber

This enables a user to build a complete system using these options. It is important to note that not all packages will build correctly to start with.

Quoted 5 lines

So perhaps you could make another patch that extends the autobuilders to test
this option. Just modify utils/genrandconfig and in the gen_config function
randomly enable these options.

Sure :) I've got an initial patchset of half dozen packages we've fixed but I'm working upstreaming on some of them first before submitting here.

Another thing to note.... As things still build with various hardening flags possibly taking affect our not, we validated the configurations took affect by using the checksec.sh tool against all target binaries post- build then
went through fixing packages. I've been thinking about how to do this
checking..... I think at a minimum, I should add the test tool to this series and at least one buildroot test case to cover a static set of packages we've fixed so far. The other option would be a more active check post build that validates all target elfs are compliant.

Quoted 14 lines

Config.in endchoice · line 756

Quoted 7 lines
Config.in +7 -0
+
+config BR2_RELRO_FULL
+ bool "Full"
+ help
+ This option includes the partial configuration, but also
+ marks the GOT as read-only at the cost of initialization time
+ during program loading, i.e every time an executable is started.

Do these options make sense at all in static linking? Isn't it implicit then
(text is always readonly I think)? -pie is certainly invalid in static linking
(at least with uClibc).

Quoted 4 lines

Also, does it make sense on NOMMU, even shared? I mean, "readonly" doesn't mean
much when there is no MMU I think...

For both of those, I agree it doesn't make sense for static or NOMMU but I have asked my developer just to be sure.

Quoted 28 lines
Quoted 28 lines
Config.in +28 -0
+
+endchoice
+
+choice
+ bool "Buffer-overflow Detection (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.
+
+config BR2_FORTIFY_SOURCE_NONE
+ bool "None"
+ help
+ Enables additional checks to detect buffer-overflows.
+
+config BR2_FORTIFY_SOURCE_1
+ bool "Conservative"
+ help
+ This option sets _FORTIFY_SOURCE set to 1 and only introduces
+ checks that shouldn't change the behavior of conforming programs.
+ Adds checks at compile-time only.
+
+config BR2_FORTIFY_SOURCE_2
+ bool "Aggressive"
+ help
+ This option sets _FORTIFY_SOURCES set to 2 and some more checking
Quoted 9 lines
Quoted 3 lines

+ is added, but some conforming programs might fail.
+ Also adds checks at run-time (detected buffer overflow terminates
+ the program)

Do you know how these behave in uClibc and musl? Waldemar, any idea? Obviously
the gcc part will still be activated, which covers about half of the functionality.

Quoted 3 lines

Checking on the answer, but we ran through the complete test-pkg build list. I'll see which were skipped. We didn't see specific failures.

The set of test packages I used ended up forcing a glibc only test-pkg build. I'll rerun with a basic busybox scenario.

Quoted 77 lines
Quoted 26 lines
Quoted 26 lines
Config.in +3 -0
+
+endchoice
+

endmenu

source "toolchain/Config.in"

package/Makefile.in +3 -0
index a1a5316..c99361f 100644
@@ -144,6 +144,9 @@ TARGET_CXXFLAGS = $(TARGET_CFLAGS)
 TARGET_FCFLAGS = $(TARGET_ABI) $(TARGET_OPTIMIZATION) $(TARGET_DEBUGGING)
 TARGET_LDFLAGS = $(call qstrip,$(BR2_TARGET_LDFLAGS))
 
+TARGET_CFLAGS_RELRO = -Wl,-z,relro
+TARGET_CFLAGS_RELRO_FULL = -Wl,-z,now $(TARGET_CFLAGS_RELRO)
+
 ifeq ($(BR2_BINFMT_FLAT),y)

TARGET_CFLAGS += $(if $($(PKG)_FLAT_STACKSIZE),-Wl$(comma)-elf2flt=-s$($(PKG)_FLAT_STACKSIZE),\

package/Makefile.in +0 -1
-Wl$(comma)-elf2flt)
@@ -181,6 +184,28 @@ TARGET_CXXFLAGS += -fstack-protector-all

TARGET_FCFLAGS += -fstack-protector-all
endif

Quoted 13 lines

package/Makefile.in TARGET_CXXFLAGS += -fstack-protector-all · line 190

Quoted 4 lines
package/Makefile.in +4 -0
+ifeq ($(BR2_RELRO_PARTIAL),y)
+TARGET_CFLAGS += $(TARGET_CFLAGS_RELRO)
+TARGET_CXXFLAGS += $(TARGET_CFLAGS_RELRO)
+TARGET_FCFLAGS += $(TARGET_CFLAGS_RELRO)

Since these are linker flags, it _should_ be sufficient to add them to LDFLAGS.
There may be some packages that don't listen to LDFLAGS so in that sense it
could be a good idea to add it to CFLAGS as well, but I tend to prefer to fix
the packages. Only, there is no easy way to detect that LDFLAGS are ignored.

What we ended up with here worked for a large test build ( lots of packages in a glibc embedded router configuration) and passed a minimal test-pkg cfg. That being said, we could go back and try flag combos but I know a few of them can't be in the linker vs just cflags (and vice versa).

Quoted 15 lines

package/Makefile.in TARGET_CXXFLAGS += -fstack-protector-all · line 201

Quoted 12 lines
package/Makefile.in +11 -0
+TARGET_LDFLAGS += $(TARGET_CFLAGS_RELRO)
+else ifeq ($(BR2_RELRO_FULL),y)
+TARGET_CFLAGS += -fPIE $(TARGET_CFLAGS_RELRO_FULL)
+TARGET_CXXFLAGS += -fPIE $(TARGET_CFLAGS_RELRO_FULL)
+TARGET_FCFLAGS += -fPIE $(TARGET_CFLAGS_RELRO_FULL)
+TARGET_LDFLAGS += -pie
+endif
+
+ifeq ($(BR2_FORTIFY_SOURCE_1),y)
+TARGET_CFLAGS += -D_FORTIFY_SOURCE=1
+TARGET_CXXFLAGS += -D_FORTIFY_SOURCE=1

It should go into CPPFLAGS (which automatically goes into CFLAGS and CXXFLAGS).

Nice that cleans it up

Quoted 7 lines
Quoted 2 lines

+TARGET_FCFLAGS += -D_FORTIFY_SOURCE=1

FCFLAGS indeed needs to be handled separately. Except: is FORTIFY valid/useful
for Fortran?

It is not, shoot we got that feedback on the RFC. I'll remove it this time.

Matt

Signature · 8 lines
Matthew L Weber / Pr Software Engineer
Airborne Information Systems / Security Systems and Software / Secure Platforms
MS 131-100, C Ave NE, Cedar Rapids, IA, 52498, USA
www.rockwellcollins.com

Note: Any Export License Required Information and License Restricted
Third Party Intellectual Property (TPIP) content must be encrypted and
sent to matthew.weber at corp.rockwellcollins.com.
#5 lore raw

PATCH v2 2/2 security hardening: add RELFO, FORTIFY options

Matt, please snip away some text when replying to a long mail, otherwise it's
difficult to find back your answer in the middle of the long quote.

Quoted 7 lines · Matthew Weber

Arnout,

Quoted 3 lines · Matthew Weber

Arnout,

On Mon, Nov 6, 2017 at 3:14 PM, Arnout Vandecappelle <[email protected]> wrote:

[snip]

Quoted 6 lines
Quoted 6 lines
Quoted 5 lines

Do you know how these behave in uClibc and musl? Waldemar, any idea? Obviously
the gcc part will still be activated, which covers about half of the functionality.

Quoted 6 lines
Quoted 3 lines

Checking on the answer, but we ran through the complete test-pkg build list. I'll see which were skipped. We didn't see specific failures.

The set of test packages I used ended up forcing a glibc only test-pkg build. I'll rerun with a basic busybox scenario.

It will build, that's for sure. My question is: will it actually do anything
useful? The effect of fortify is shared a bit between GCC and glibc. E.g. 'memset' has a GCC implementation (used when it can be inlined) and a glibc implementation (used when it's too big or unpredictable). As far as I can see, neither uClibc nor musl have support for FORTIFY. So only the GCC part will take effect. But I think that that is so little that it's hardly worth it.

Regards,
Arnout

Signature · 6 lines
Arnout Vandecappelle                          arnout at mind be
Senior Embedded Software Architect            +32-16-286500
Essensium/Mind                                http://www.mind.be
G.Geenslaan 9, 3001 Leuven, Belgium           BE 872 984 063 RPR Leuven
LinkedIn profile: http://www.linkedin.com/in/arnoutvandecappelle
GPG fingerprint:  7493 020B C7E3 8618 8DEC 222C 82EB F404 F9AC 0DDF
#6 lore raw

PATCH v2 2/2 security hardening: add RELFO, FORTIFY options

Hi Arnout,
Arnout Vandecappelle wrote,

Quoted 13 lines
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines

Do you know how these behave in uClibc and musl? Waldemar, any idea? Obviously
the gcc part will still be activated, which covers about half of the functionality.

Quoted 6 lines
Quoted 3 lines

Checking on the answer, but we ran through the complete test-pkg build list. I'll see which were skipped. We didn't see specific failures.

The set of test packages I used ended up forcing a glibc only test-pkg build. I'll rerun with a basic busybox scenario.

Quoted 6 lines

It will build, that's for sure. My question is: will it actually do anything
useful? The effect of fortify is shared a bit between GCC and glibc. E.g. 'memset' has a GCC implementation (used when it can be inlined) and a glibc implementation (used when it's too big or unpredictable). As far as I can see, neither uClibc nor musl have support for FORTIFY. So only the GCC part will take effect. But I think that that is so little that it's hardly worth it.

I can confirm uClibc-ng does not support FORTIFY security mechanisms.
There is some old unused code since 82098ab9b853c33ee8ade61c9510b295cc696de1, but I am considering removing it, because it is unused and incomplete.

best regards
Waldemar

#7 lore raw

PATCH v2 2/2 security hardening: add RELFO, FORTIFY options

Quoted 23 lines · Waldemar Brodkorb

Hi Arnout,
Arnout Vandecappelle wrote,

Quoted 13 lines
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines

Do you know how these behave in uClibc and musl? Waldemar, any idea? Obviously
the gcc part will still be activated, which covers about half of the functionality.

Quoted 6 lines
Quoted 3 lines

Checking on the answer, but we ran through the complete test-pkg build list. I'll see which were skipped. We didn't see specific failures.

The set of test packages I used ended up forcing a glibc only test-pkg build. I'll rerun with a basic busybox scenario.

Quoted 6 lines

It will build, that's for sure. My question is: will it actually do anything
useful? The effect of fortify is shared a bit between GCC and glibc. E.g. 'memset' has a GCC implementation (used when it can be inlined) and a glibc implementation (used when it's too big or unpredictable). As far as I can see, neither uClibc nor musl have support for FORTIFY. So only the GCC part will take effect. But I think that that is so little that it's hardly worth it.

Quoted 5 lines

I can confirm uClibc-ng does not support FORTIFY security mechanisms.
There is some old unused code since 82098ab9b853c33ee8ade61c9510b295cc696de1, but I am considering removing it, because it is unused and incomplete.

So I did a little bit more research [1], and it looks like a significant part
of the FORTIFY support comes from gcc. However, the gcc support is only activated if the appropriate header is included that replaces memcpy with __builtin___memcpy_chk etc.

In addition, GCC's check will call __fortify_fail if the check fails. So you
can easily find out if it's supported: does the libc define __fortify_fail or not? Neither uClibc nor musl does.

In short, the fortify options should depend on glibc.

Regards,
Arnout

[1] https://access.redhat.com/blogs/766093/posts/1976213

Signature · 6 lines
Arnout Vandecappelle                          arnout at mind be
Senior Embedded Software Architect            +32-16-286500
Essensium/Mind                                http://www.mind.be
G.Geenslaan 9, 3001 Leuven, Belgium           BE 872 984 063 RPR Leuven
LinkedIn profile: http://www.linkedin.com/in/arnoutvandecappelle
GPG fingerprint:  7493 020B C7E3 8618 8DEC 222C 82EB F404 F9AC 0DDF
#8 lore raw

PATCH v2 2/2 security hardening: add RELFO, FORTIFY options

In reply to Arnout Vandecappelle

6.11.2017, 23:14, Arnout Vandecappelle kirjoitti:

Quoted 9 lines
package/Makefile.in +4 -0
@@ -181,6 +184,28 @@ TARGET_CXXFLAGS += -fstack-protector-all
  TARGET_FCFLAGS += -fstack-protector-all
  endif
 
+ifeq ($(BR2_RELRO_PARTIAL),y)
+TARGET_CFLAGS += $(TARGET_CFLAGS_RELRO)
+TARGET_CXXFLAGS += $(TARGET_CFLAGS_RELRO)
+TARGET_FCFLAGS += $(TARGET_CFLAGS_RELRO)
  Since these are linker flags, it _should_ be sufficient to add them to LDFLAGS.
Quoted 4 lines

There may be some packages that don't listen to LDFLAGS so in that sense it could be a good idea to add it to CFLAGS as well, but I tend to prefer to fix the packages. Only, there is no easy way to detect that LDFLAGS are ignored.

There could be a way to tell if package shows middle finger to CFLAGS/CXXFLAGS/LDFLAGS
and just ignores the hardening options.

There's a little perl script called hardening-check that could be used to do post installation checking
of what packages actually respected the flags.

http://manpages.ubuntu.com/manpages/trusty/man1/hardening-check.1.html

I have a copy of that perl script here:
https://www.orwell1984.today/hardening-check

I also did the following little test:
1. First compiled turbovnc against i686-uclibc without any hardening and then running
"hardening-check -c output/target/usr/bin/Xvnc" with following results:

output/target/usr/bin/Xvnc:
Position Independent Executable: no, normal executable! Stack protected: no, not found!
Fortify Source functions: no, only unprotected functions found! Read-only relocations: yes
Immediate binding: no, not found!

2. Then forced the gcc compiler to use hardening features by using GCC Spec File, so that
if turbovnc did ignore CFLAGS/CXXFLAGS/LDFLAGS it would still be forcefeed the right
hardening options, like this:

- Dump the built-in specs file "$(HOST_CC) -dumpspecs > specs" and then edit it
to enable all the hardening stuff
(here's mine for i686-uclibc, forgot to enable stack-protection:
https://www.orwell1984.today/specs)

- Find location where gcc looks for specs file "dirname $($(HOST_CC) --print-libgcc-file-name)"
and move the edited specs file there

- Rebuild turbovnc

- And finally, check "hardening-check -c output/target/usr/bin/Xvnc" with following result:

output/target/usr/bin/Xvnc:
Position Independent Executable: yes
Stack protected: no, not found!
Fortify Source functions: no, only unprotected functions found! Read-only relocations: yes
Immediate binding: yes

Here turbovnc built with pie, relro,now and if I would have remember to enable stack protection in toolchain,
also with stack protection.

So that's a one way to force & check hardening afterwards. But have to admit, not very elegant way.

Maybe there could be hardened directory with some premade "profiles" (gcc spec files) for various arch-lib combos
which could be selected from menu and then the buildroot cross-compiler would have
it's dirname $($HOST_CC) --print-libgcc-file-name/specs be a just symlink to that arch-lib combos like this:

output/host/lib/gcc/i686-buildroot-linux-uclibc/6.4.0/specs --> ../../../../../../hardened/i686/uclibc/specs

If selecting vanilla, non-hardened toolchain from menu, it would just remove the symlink.
And maybe there could be an option to run hardening-check script at the end of installation.

Just throwing thoughts around
-S-

#9 lore raw

PATCH v2 2/2 security hardening: add RELFO, FORTIFY options

Quoted 20 lines · Stefan Fr?berg

6.11.2017, 23:14, Arnout Vandecappelle kirjoitti:

Quoted 7 lines
(quoted diff) +0 -0
@@ -181,6 +184,28 @@ TARGET_CXXFLAGS += -fstack-protector-all

? TARGET_FCFLAGS += -fstack-protector-all
? endif
? +ifeq ($(BR2_RELRO_PARTIAL),y)

package/Makefile.in +3 -0
+TARGET_CFLAGS += $(TARGET_CFLAGS_RELRO)
+TARGET_CXXFLAGS += $(TARGET_CFLAGS_RELRO)
+TARGET_FCFLAGS += $(TARGET_CFLAGS_RELRO)
Quoted 5 lines

? Since these are linker flags, it _should_ be sufficient to add them to LDFLAGS. There may be some packages that don't listen to LDFLAGS so in that sense it could be a good idea to add it to CFLAGS as well, but I tend to prefer to fix the packages. Only, there is no easy way to detect that LDFLAGS are ignored.

There could be a way to tell if package shows middle finger to CFLAGS/CXXFLAGS/LDFLAGS
and just ignores the hardening options.

Quoted 8 lines

There's a little perl script called hardening-check that could be used to do post installation checking
of what packages actually respected the flags.

http://manpages.ubuntu.com/manpages/trusty/man1/hardening-check.1.html

I have a copy of that perl script here:
https://www.orwell1984.today/hardening-check

Yeah, Matthew already proposed to include a (different) hardening check script.
I think that that's a good idea.

[snip]

Quoted 11 lines

Maybe there could be hardened directory with some premade "profiles" (gcc spec files) for various arch-lib combos
which could be selected from menu and then the buildroot cross-compiler would have it's dirname $($HOST_CC) --print-libgcc-file-name/specs be a just symlink to that arch-lib combos like this:

output/host/lib/gcc/i686-buildroot-linux-uclibc/6.4.0/specs --> ../../../../../../hardened/i686/uclibc/specs

If selecting vanilla, non-hardened toolchain from menu, it would just remove the symlink.

Hm, I think messing with the specs file is making things complicated...

However, we do have a toolchain wrapper and we could add the hardening options
in there instead of in CFLAGS. One small caveat, however: some packages may not build at all with some of the hardening options (-pie for example), in particular bootloaders and kernels are prone to be problematic. Otherwise it sounds like a viable option though.

Quoted 2 lines

And maybe there could be an option to run hardening-check script at the end of installation.

Yep, certainly.

Regards,
Arnout

Quoted 13 lines

Just throwing thoughts around
-S-

Signature · 6 lines
Arnout Vandecappelle                          arnout at mind be
Senior Embedded Software Architect            +32-16-286500
Essensium/Mind                                http://www.mind.be
G.Geenslaan 9, 3001 Leuven, Belgium           BE 872 984 063 RPR Leuven
LinkedIn profile: http://www.linkedin.com/in/arnoutvandecappelle
GPG fingerprint:  7493 020B C7E3 8618 8DEC 222C 82EB F404 F9AC 0DDF