1515def write_testcode (filename ):
1616 with open (filename , 'w' , encoding = "utf8" ) as f :
1717 f .write ('''
18- #include <stdio.h >
18+ #include <cstdio >
1919 int main()
2020 {
21- printf("the quick brown fox jumps over the lazy god\\ n");
21+ std:: printf("the quick brown fox jumps over the lazy god\\ n");
2222 return 0;
2323 }
2424 ''' )
@@ -34,111 +34,111 @@ def env_flags() -> list[str]:
3434 # See the definitions for ac_link in autoconf's lib/autoconf/c.m4 file for
3535 # reference.
3636 flags : list [str ] = []
37- for var in ['CFLAGS ' , 'CPPFLAGS' , 'LDFLAGS' ]:
37+ for var in ['CXXFLAGS ' , 'CPPFLAGS' , 'LDFLAGS' ]:
3838 flags += filter (None , os .environ .get (var , '' ).split (' ' ))
3939 return flags
4040
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 )
4343 p = subprocess .run ([os .path .join (os .path .dirname (__file__ ), 'security-check.py' ), executable ], stdout = subprocess .PIPE , text = True )
4444 return (p .returncode , p .stdout .rstrip ())
4545
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 )
4848 binary = lief .parse (executable )
4949 arch = binary .abstract .header .architecture
5050 os .remove (executable )
5151 return arch
5252
5353class TestSecurityChecks (unittest .TestCase ):
5454 def test_ELF (self ):
55- source = 'test1.c '
55+ source = 'test1.cpp '
5656 executable = 'test1'
57- cc = determine_wellknown_cmd ('CC ' , 'gcc ' )
57+ cxx = determine_wellknown_cmd ('CXX ' , 'g++ ' )
5858 write_testcode (source )
59- arch = get_arch (cc , source , executable )
59+ arch = get_arch (cxx , source , executable )
6060
6161 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' ]),
6363 (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' ]),
6565 (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' ]),
6767 (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' ]),
6969 (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' ]),
7171 (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' ]),
7373 (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' ]),
7575 (0 , '' ))
7676 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' ]),
7878 (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' ]),
8080 (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' ]),
8282 (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' ]),
8484 (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' ]),
8686 (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' ]),
8888 (0 , '' ))
8989
9090 clean_files (source , executable )
9191
9292 def test_PE (self ):
93- source = 'test1.c '
93+ source = 'test1.cpp '
9494 executable = 'test1.exe'
95- cc = determine_wellknown_cmd ('CC ' , 'x86_64-w64-mingw32-gcc ' )
95+ cxx = determine_wellknown_cmd ('CXX ' , 'x86_64-w64-mingw32-g++ ' )
9696 write_testcode (source )
9797
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' ]),
9999 (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' ]),
101101 (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' ]),
103103 (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' ]),
105105 (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' ]),
107107 (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' ]),
109109 (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' ]),
111111 (0 , '' ))
112112
113113 clean_files (source , executable )
114114
115115 def test_MACHO (self ):
116- source = 'test1.c '
116+ source = 'test1.cpp '
117117 executable = 'test1'
118- cc = determine_wellknown_cmd ('CC ' , 'clang' )
118+ cxx = determine_wellknown_cmd ('CXX ' , 'clang++ ' )
119119 write_testcode (source )
120- arch = get_arch (cc , source , executable )
120+ arch = get_arch (cxx , source , executable )
121121
122122 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' ]),
124124 (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' ]),
126126 (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' ]),
128128 (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' ]),
130130 (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' ]),
132132 (0 , '' ))
133133 else :
134134 # 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' ]),
136136 (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' ]),
138138 (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' ]),
140140 (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' ]),
142142 (0 , '' ))
143143
144144
0 commit comments