From 469a5bc4fa74d70556cce454efbc38fb7945acd8 Mon Sep 17 00:00:00 2001 From: fanquake Date: Sun, 9 May 2021 11:32:59 +0800 Subject: [PATCH 1/2] build: build Boost with -fcf-protection when targeting Darwin The LLVM Clang we use for cross-compilation supports this option, and it's expected that any builders on macOS will also be using an Apple Clang that supports it. --- depends/packages/boost.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 0800c63dfc2..6b3b2931403 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -26,6 +26,7 @@ $(package)_config_libraries=filesystem,system,test $(package)_cxxflags=-std=c++17 -fvisibility=hidden $(package)_cxxflags_linux=-fPIC $(package)_cxxflags_android=-fPIC +$(package)_cxxflags_darwin=-fcf-protection=full endef define $(package)_preprocess_cmds From 42b589d18fed5e2b3cb6ac9937e3333619967a6c Mon Sep 17 00:00:00 2001 From: fanquake Date: Sun, 9 May 2021 11:33:41 +0800 Subject: [PATCH 2/2] scripts: test for MACHO control flow instrumentation --- contrib/devtools/security-check.py | 16 +++++++++++++++- contrib/devtools/test-security-check.py | 12 +++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py index b6628c2ad5c..0b59d8eada6 100755 --- a/contrib/devtools/security-check.py +++ b/contrib/devtools/security-check.py @@ -188,6 +188,19 @@ def check_NX(executable) -> bool: binary = lief.parse(executable) return binary.has_nx +def check_control_flow(executable) -> bool: + ''' + Check for control flow instrumentation + ''' + binary = lief.parse(executable) + + content = binary.get_content_from_virtual_address(binary.entrypoint, 4, lief.Binary.VA_TYPES.AUTO) + + if content == [243, 15, 30, 250]: # endbr64 + return True + return False + + CHECKS = { 'ELF': [ ('PIE', check_ELF_PIE), @@ -208,7 +221,8 @@ CHECKS = { ('NOUNDEFS', check_MACHO_NOUNDEFS), ('NX', check_NX), ('LAZY_BINDINGS', check_MACHO_LAZY_BINDINGS), - ('Canary', check_MACHO_Canary) + ('Canary', check_MACHO_Canary), + ('CONTROL_FLOW', check_control_flow), ] } diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py index 28b5f57489d..c079fe5b4d1 100755 --- a/contrib/devtools/test-security-check.py +++ b/contrib/devtools/test-security-check.py @@ -77,16 +77,18 @@ class TestSecurityChecks(unittest.TestCase): write_testcode(source) self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fno-stack-protector']), - (1, executable+': failed PIE NOUNDEFS NX LAZY_BINDINGS Canary')) + (1, executable+': failed PIE NOUNDEFS NX LAZY_BINDINGS Canary CONTROL_FLOW')) self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fstack-protector-all']), - (1, executable+': failed PIE NOUNDEFS NX LAZY_BINDINGS')) + (1, executable+': failed PIE NOUNDEFS NX LAZY_BINDINGS CONTROL_FLOW')) self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-fstack-protector-all']), - (1, executable+': failed PIE NOUNDEFS LAZY_BINDINGS')) + (1, executable+': failed PIE NOUNDEFS LAZY_BINDINGS CONTROL_FLOW')) self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-fstack-protector-all']), - (1, executable+': failed PIE LAZY_BINDINGS')) + (1, executable+': failed PIE LAZY_BINDINGS CONTROL_FLOW')) self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-bind_at_load','-fstack-protector-all']), + (1, executable+': failed PIE CONTROL_FLOW')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-bind_at_load','-fstack-protector-all', '-fcf-protection=full']), (1, executable+': failed PIE')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-pie','-Wl,-bind_at_load','-fstack-protector-all']), + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-pie','-Wl,-bind_at_load','-fstack-protector-all', '-fcf-protection=full']), (0, '')) clean_files(source, executable)