--- /dev/null
+# Fortify Source
+# Inputs: hardening_features
+
+fortify_source_opt = get_option('fortify-source')
+
+if fortify_source_opt != 'disabled'
+ fortify_source_level = 2
+ if fortify_source_opt == 'auto'
+ fortify_source_level = 3
+ else
+ fortify_source_level = fortify_source_opt.to_int()
+ endif
+
+ variants = [3, 2, 1]
+ foreach variant: variants
+ variant_str = variant.to_string()
+ if fortify_source_level == variant
+ if cxx.has_argument('-D_FORTIFY_SOURCE=' + variant_str)
+ add_project_arguments('-U_FORTIFY_SOURCE', '-D_FORTIFY_SOURCE=' + variant_str, language: 'cpp')
+ break
+ else
+ fortify_source_level = fortify_source_level - 1
+ endif
+ endif
+ endforeach
+
+ if fortify_source_level == 0
+ fortify_source_level = 'no'
+ endif
+
+ hardening_features += [[fortify_source_level != 0, 'Source Fortification']]
+ summary('Source Fortification Level', fortify_source_level, section: 'Hardening')
+endif
--- /dev/null
+# Read-only Global Offset Table
+# Inputs: hardening_features
+
+ld_help = run_command(cxx, '-Wl,-help', '2>&1', check: true).stdout().strip()
+variants = ['relro', 'now']
+found_variant = false
+foreach variant: variants
+ if ld_help.contains('-z ' + variant)
+ found_variant = true
+ add_project_link_arguments('-Wl,-z', '-Wl,' + variant, language: 'cpp')
+ endif
+endforeach
+
+hardening_features += [[found_variant, 'Read-only Global Offset Table']]
+summary('Read-only GOT', found_variant, bool_yn: true, section: 'Hardening')
--- /dev/null
+# Hardening
+opt_hardening = get_option('hardening')
+
+if opt_hardening.enabled() or opt_hardening.auto()
+ hardening_features = []
+
+ subdir('pie') # PIE
+ subdir('stack-prot') # Stack Protector
+ subdir('stack-smashing-prot') # Stack-Smashing Protection
+ subdir('fortify-source') # Fortify Source
+ subdir('global-offset-table') # Read-only Global Offset Table
+
+ foreach feature: hardening_features
+ available = feature[0]
+ name = feature[1]
+
+ if not available
+ if opt_hardening.auto()
+ warning(name + ' is not supported')
+ else
+ error('Failing because ' + name + ' is not supported but hardening was explicitly requested')
+ endif
+ endif
+ endforeach
+endif
--- /dev/null
+# PIE
+# Inputs: hardening_features conf
+
+prog = '''
+#include <pthread.h>
+__thread unsigned int t_id;
+
+int main() {
+ t_id = 1;
+ return 0;
+}
+'''
+
+found_variant = false
+if system == 'windows' and system == 'cygwin'
+ # All code is position independent on Win32 targets.
+ found_variant = true
+else
+ pie_variants = [
+ [['-fPIE', '-DPIE'], ['-pie']],
+ [['-fPIE', '-DPIE'], ['-Wl,-pie']],
+ ]
+ foreach variant: pie_variants
+ cflags = variant[0]
+ ldflags = variant[1]
+
+ if cxx.links(prog, args: cflags + ldflags, name: 'compiler can build Position Independent Executables')
+ add_project_arguments(cflags, language: 'cpp')
+ add_project_link_arguments(ldflags, language: 'cpp')
+ found_variant = true
+ break
+ endif
+ endforeach
+endif
+
+hardening_features += [[found_variant, 'Building position independent executables (PIEs)']]
+conf.set10('PIE', found_variant, description: 'Whether we enable building a Position Independent Executable (PIE)')
+summary('PIE', found_variant, bool_yn: true, section: 'Hardening')
--- /dev/null
+# Stack Protector
+# Inputs: hardening_features
+
+support_stack_protector = cxx.has_argument('-fstack-protector')
+
+if support_stack_protector
+ add_project_arguments('-fstack-protector', language: ['c', 'cpp'])
+endif
+
+hardening_features += [[support_stack_protector, 'Stack Protector']]
+summary('Stack Protector', support_stack_protector, bool_yn: true, section: 'Hardening')
--- /dev/null
+# Stack-smashing Protection
+# Inputs: hardening_features
+
+support_stack_smashing_protector = cxx.has_argument('--param=ssp-buffer-size=4')
+if support_stack_smashing_protector
+ add_global_arguments(['--param=ssp-buffer-size=4'], language: ['c', 'cpp'])
+endif
+
+hardening_features += [[support_stack_smashing_protector, 'Stack Smashing Protection']]
+summary('Stack Smashing Protection', support_stack_smashing_protector, bool_yn: true, section: 'Hardening')
+if support_stack_smashing_protector
+ summary('SSP Buffer Size', 4, section: 'Hardening')
+endif