@@ -38,13 +38,13 @@ def env_flags() -> list[str]:
38
38
flags += filter (None , os .environ .get (var , '' ).split (' ' ))
39
39
return flags
40
40
41
- def call_security_check (cc : str , source : str , executable : str , options ) -> tuple :
42
- subprocess .run ([* cc ,source ,'-o' ,executable ] + env_flags () + options , check = True )
41
+ def call_security_check (cxx : str , source : str , executable : str , options ) -> tuple :
42
+ subprocess .run ([* cxx ,source ,'-o' ,executable ] + env_flags () + options , check = True )
43
43
p = subprocess .run ([os .path .join (os .path .dirname (__file__ ), 'security-check.py' ), executable ], stdout = subprocess .PIPE , text = True )
44
44
return (p .returncode , p .stdout .rstrip ())
45
45
46
- def get_arch (cc , source , executable ):
47
- subprocess .run ([* cc , source , '-o' , executable ] + env_flags (), check = True )
46
+ def get_arch (cxx , source , executable ):
47
+ subprocess .run ([* cxx , source , '-o' , executable ] + env_flags (), check = True )
48
48
binary = lief .parse (executable )
49
49
arch = binary .abstract .header .architecture
50
50
os .remove (executable )
@@ -54,91 +54,91 @@ class TestSecurityChecks(unittest.TestCase):
54
54
def test_ELF (self ):
55
55
source = 'test1.cpp'
56
56
executable = 'test1'
57
- cc = determine_wellknown_cmd ('CXX' , 'g++' )
57
+ cxx = determine_wellknown_cmd ('CXX' , 'g++' )
58
58
write_testcode (source )
59
- arch = get_arch (cc , source , executable )
59
+ arch = get_arch (cxx , source , executable )
60
60
61
61
if arch == lief .ARCHITECTURES .X86 :
62
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-zexecstack' ,'-Wl,-znorelro' ,'-no-pie' ,'-fno-PIE' , '-Wl,-z,separate-code' ]),
62
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-zexecstack' ,'-Wl,-znorelro' ,'-no-pie' ,'-fno-PIE' , '-Wl,-z,separate-code' ]),
63
63
(1 , executable + ': failed PIE NX RELRO CONTROL_FLOW' ))
64
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-znorelro' ,'-no-pie' ,'-fno-PIE' , '-Wl,-z,separate-code' ]),
64
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-znorelro' ,'-no-pie' ,'-fno-PIE' , '-Wl,-z,separate-code' ]),
65
65
(1 , executable + ': failed PIE RELRO CONTROL_FLOW' ))
66
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-znorelro' ,'-no-pie' ,'-fno-PIE' , '-Wl,-z,separate-code' ]),
66
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-znorelro' ,'-no-pie' ,'-fno-PIE' , '-Wl,-z,separate-code' ]),
67
67
(1 , executable + ': failed PIE RELRO CONTROL_FLOW' ))
68
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-znorelro' ,'-pie' ,'-fPIE' , '-Wl,-z,separate-code' ]),
68
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-znorelro' ,'-pie' ,'-fPIE' , '-Wl,-z,separate-code' ]),
69
69
(1 , executable + ': failed RELRO CONTROL_FLOW' ))
70
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-zrelro' ,'-Wl,-z,now' ,'-pie' ,'-fPIE' , '-Wl,-z,noseparate-code' ]),
70
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-zrelro' ,'-Wl,-z,now' ,'-pie' ,'-fPIE' , '-Wl,-z,noseparate-code' ]),
71
71
(1 , executable + ': failed separate_code CONTROL_FLOW' ))
72
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-zrelro' ,'-Wl,-z,now' ,'-pie' ,'-fPIE' , '-Wl,-z,separate-code' ]),
72
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-zrelro' ,'-Wl,-z,now' ,'-pie' ,'-fPIE' , '-Wl,-z,separate-code' ]),
73
73
(1 , executable + ': failed CONTROL_FLOW' ))
74
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-zrelro' ,'-Wl,-z,now' ,'-pie' ,'-fPIE' , '-Wl,-z,separate-code' , '-fcf-protection=full' ]),
74
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-zrelro' ,'-Wl,-z,now' ,'-pie' ,'-fPIE' , '-Wl,-z,separate-code' , '-fcf-protection=full' ]),
75
75
(0 , '' ))
76
76
else :
77
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-zexecstack' ,'-Wl,-znorelro' ,'-no-pie' ,'-fno-PIE' , '-Wl,-z,separate-code' ]),
77
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-zexecstack' ,'-Wl,-znorelro' ,'-no-pie' ,'-fno-PIE' , '-Wl,-z,separate-code' ]),
78
78
(1 , executable + ': failed PIE NX RELRO' ))
79
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-znorelro' ,'-no-pie' ,'-fno-PIE' , '-Wl,-z,separate-code' ]),
79
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-znorelro' ,'-no-pie' ,'-fno-PIE' , '-Wl,-z,separate-code' ]),
80
80
(1 , executable + ': failed PIE RELRO' ))
81
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-znorelro' ,'-no-pie' ,'-fno-PIE' , '-Wl,-z,separate-code' ]),
81
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-znorelro' ,'-no-pie' ,'-fno-PIE' , '-Wl,-z,separate-code' ]),
82
82
(1 , executable + ': failed PIE RELRO' ))
83
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-znorelro' ,'-pie' ,'-fPIE' , '-Wl,-z,separate-code' ]),
83
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-znorelro' ,'-pie' ,'-fPIE' , '-Wl,-z,separate-code' ]),
84
84
(1 , executable + ': failed RELRO' ))
85
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-zrelro' ,'-Wl,-z,now' ,'-pie' ,'-fPIE' , '-Wl,-z,noseparate-code' ]),
85
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-zrelro' ,'-Wl,-z,now' ,'-pie' ,'-fPIE' , '-Wl,-z,noseparate-code' ]),
86
86
(1 , executable + ': failed separate_code' ))
87
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-zrelro' ,'-Wl,-z,now' ,'-pie' ,'-fPIE' , '-Wl,-z,separate-code' ]),
87
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-znoexecstack' ,'-Wl,-zrelro' ,'-Wl,-z,now' ,'-pie' ,'-fPIE' , '-Wl,-z,separate-code' ]),
88
88
(0 , '' ))
89
89
90
90
clean_files (source , executable )
91
91
92
92
def test_PE (self ):
93
93
source = 'test1.cpp'
94
94
executable = 'test1.exe'
95
- cc = determine_wellknown_cmd ('CXX' , 'x86_64-w64-mingw32-g++' )
95
+ cxx = determine_wellknown_cmd ('CXX' , 'x86_64-w64-mingw32-g++' )
96
96
write_testcode (source )
97
97
98
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,--disable-nxcompat' ,'-Wl,--disable-reloc-section' ,'-Wl,--disable-dynamicbase' ,'-Wl,--disable-high-entropy-va' ,'-no-pie' ,'-fno-PIE' ,'-fno-stack-protector' ]),
98
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,--disable-nxcompat' ,'-Wl,--disable-reloc-section' ,'-Wl,--disable-dynamicbase' ,'-Wl,--disable-high-entropy-va' ,'-no-pie' ,'-fno-PIE' ,'-fno-stack-protector' ]),
99
99
(1 , executable + ': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA NX RELOC_SECTION CONTROL_FLOW Canary' ))
100
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,--nxcompat' ,'-Wl,--disable-reloc-section' ,'-Wl,--disable-dynamicbase' ,'-Wl,--disable-high-entropy-va' ,'-no-pie' ,'-fno-PIE' ,'-fstack-protector-all' , '-lssp' ]),
100
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,--nxcompat' ,'-Wl,--disable-reloc-section' ,'-Wl,--disable-dynamicbase' ,'-Wl,--disable-high-entropy-va' ,'-no-pie' ,'-fno-PIE' ,'-fstack-protector-all' , '-lssp' ]),
101
101
(1 , executable + ': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA RELOC_SECTION CONTROL_FLOW' ))
102
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,--nxcompat' ,'-Wl,--enable-reloc-section' ,'-Wl,--disable-dynamicbase' ,'-Wl,--disable-high-entropy-va' ,'-no-pie' ,'-fno-PIE' ,'-fstack-protector-all' , '-lssp' ]),
102
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,--nxcompat' ,'-Wl,--enable-reloc-section' ,'-Wl,--disable-dynamicbase' ,'-Wl,--disable-high-entropy-va' ,'-no-pie' ,'-fno-PIE' ,'-fstack-protector-all' , '-lssp' ]),
103
103
(1 , executable + ': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA CONTROL_FLOW' ))
104
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,--nxcompat' ,'-Wl,--enable-reloc-section' ,'-Wl,--disable-dynamicbase' ,'-Wl,--disable-high-entropy-va' ,'-pie' ,'-fPIE' ,'-fstack-protector-all' , '-lssp' ]),
104
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,--nxcompat' ,'-Wl,--enable-reloc-section' ,'-Wl,--disable-dynamicbase' ,'-Wl,--disable-high-entropy-va' ,'-pie' ,'-fPIE' ,'-fstack-protector-all' , '-lssp' ]),
105
105
(1 , executable + ': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA CONTROL_FLOW' )) # -pie -fPIE does nothing unless --dynamicbase is also supplied
106
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,--nxcompat' ,'-Wl,--enable-reloc-section' ,'-Wl,--dynamicbase' ,'-Wl,--disable-high-entropy-va' ,'-pie' ,'-fPIE' ,'-fstack-protector-all' , '-lssp' ]),
106
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,--nxcompat' ,'-Wl,--enable-reloc-section' ,'-Wl,--dynamicbase' ,'-Wl,--disable-high-entropy-va' ,'-pie' ,'-fPIE' ,'-fstack-protector-all' , '-lssp' ]),
107
107
(1 , executable + ': failed HIGH_ENTROPY_VA CONTROL_FLOW' ))
108
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,--nxcompat' ,'-Wl,--enable-reloc-section' ,'-Wl,--dynamicbase' ,'-Wl,--high-entropy-va' ,'-pie' ,'-fPIE' ,'-fstack-protector-all' , '-lssp' ]),
108
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,--nxcompat' ,'-Wl,--enable-reloc-section' ,'-Wl,--dynamicbase' ,'-Wl,--high-entropy-va' ,'-pie' ,'-fPIE' ,'-fstack-protector-all' , '-lssp' ]),
109
109
(1 , executable + ': failed CONTROL_FLOW' ))
110
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,--nxcompat' ,'-Wl,--enable-reloc-section' ,'-Wl,--dynamicbase' ,'-Wl,--high-entropy-va' ,'-pie' ,'-fPIE' , '-fcf-protection=full' ,'-fstack-protector-all' , '-lssp' ]),
110
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,--nxcompat' ,'-Wl,--enable-reloc-section' ,'-Wl,--dynamicbase' ,'-Wl,--high-entropy-va' ,'-pie' ,'-fPIE' , '-fcf-protection=full' ,'-fstack-protector-all' , '-lssp' ]),
111
111
(0 , '' ))
112
112
113
113
clean_files (source , executable )
114
114
115
115
def test_MACHO (self ):
116
116
source = 'test1.cpp'
117
117
executable = 'test1'
118
- cc = determine_wellknown_cmd ('CXX' , 'clang++' )
118
+ cxx = determine_wellknown_cmd ('CXX' , 'clang++' )
119
119
write_testcode (source )
120
- arch = get_arch (cc , source , executable )
120
+ arch = get_arch (cxx , source , executable )
121
121
122
122
if arch == lief .ARCHITECTURES .X86 :
123
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-no_pie' ,'-Wl,-flat_namespace' ,'-fno-stack-protector' , '-Wl,-no_fixup_chains' ]),
123
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-no_pie' ,'-Wl,-flat_namespace' ,'-fno-stack-protector' , '-Wl,-no_fixup_chains' ]),
124
124
(1 , executable + ': failed NOUNDEFS Canary FIXUP_CHAINS PIE CONTROL_FLOW' ))
125
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-flat_namespace' ,'-fno-stack-protector' , '-Wl,-fixup_chains' ]),
125
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-flat_namespace' ,'-fno-stack-protector' , '-Wl,-fixup_chains' ]),
126
126
(1 , executable + ': failed NOUNDEFS Canary CONTROL_FLOW' ))
127
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-flat_namespace' ,'-fstack-protector-all' , '-Wl,-fixup_chains' ]),
127
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-flat_namespace' ,'-fstack-protector-all' , '-Wl,-fixup_chains' ]),
128
128
(1 , executable + ': failed NOUNDEFS CONTROL_FLOW' ))
129
- self .assertEqual (call_security_check (cc , source , executable , ['-fstack-protector-all' , '-Wl,-fixup_chains' ]),
129
+ self .assertEqual (call_security_check (cxx , source , executable , ['-fstack-protector-all' , '-Wl,-fixup_chains' ]),
130
130
(1 , executable + ': failed CONTROL_FLOW' ))
131
- self .assertEqual (call_security_check (cc , source , executable , ['-fstack-protector-all' , '-fcf-protection=full' , '-Wl,-fixup_chains' ]),
131
+ self .assertEqual (call_security_check (cxx , source , executable , ['-fstack-protector-all' , '-fcf-protection=full' , '-Wl,-fixup_chains' ]),
132
132
(0 , '' ))
133
133
else :
134
134
# arm64 darwin doesn't support non-PIE binaries, control flow or executable stacks
135
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-flat_namespace' ,'-fno-stack-protector' , '-Wl,-no_fixup_chains' ]),
135
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-flat_namespace' ,'-fno-stack-protector' , '-Wl,-no_fixup_chains' ]),
136
136
(1 , executable + ': failed NOUNDEFS Canary FIXUP_CHAINS BRANCH_PROTECTION' ))
137
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-flat_namespace' ,'-fno-stack-protector' , '-Wl,-fixup_chains' , '-mbranch-protection=bti' ]),
137
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-flat_namespace' ,'-fno-stack-protector' , '-Wl,-fixup_chains' , '-mbranch-protection=bti' ]),
138
138
(1 , executable + ': failed NOUNDEFS Canary' ))
139
- self .assertEqual (call_security_check (cc , source , executable , ['-Wl,-flat_namespace' ,'-fstack-protector-all' , '-Wl,-fixup_chains' , '-mbranch-protection=bti' ]),
139
+ self .assertEqual (call_security_check (cxx , source , executable , ['-Wl,-flat_namespace' ,'-fstack-protector-all' , '-Wl,-fixup_chains' , '-mbranch-protection=bti' ]),
140
140
(1 , executable + ': failed NOUNDEFS' ))
141
- self .assertEqual (call_security_check (cc , source , executable , ['-fstack-protector-all' , '-Wl,-fixup_chains' , '-mbranch-protection=bti' ]),
141
+ self .assertEqual (call_security_check (cxx , source , executable , ['-fstack-protector-all' , '-Wl,-fixup_chains' , '-mbranch-protection=bti' ]),
142
142
(0 , '' ))
143
143
144
144
0 commit comments