diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py index f1639cb1f..0b74be7a4 100755 --- a/contrib/devtools/test-security-check.py +++ b/contrib/devtools/test-security-check.py @@ -1,65 +1,96 @@ #!/usr/bin/env python3 # Copyright (c) 2015-2017 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' Test script for security-check.py ''' import subprocess import unittest def write_testcode(filename): with open(filename, 'w', encoding="utf8") as f: f.write(''' #include int main() { printf("the quick brown fox jumps over the lazy god\\n"); return 0; } ''') def call_security_check(cc, source, executable, options): subprocess.check_call([cc, source, '-o', executable] + options) p = subprocess.Popen(['./security-check.py', executable], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True) (stdout, stderr) = p.communicate() return (p.returncode, stdout.rstrip()) class TestSecurityChecks(unittest.TestCase): def test_ELF(self): source = 'test1.c' executable = 'test1' cc = 'gcc' write_testcode(source) self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-zexecstack', '-fno-stack-protector', '-Wl,-znorelro']), (1, executable + ': failed PIE NX RELRO Canary')) self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack', '-fno-stack-protector', '-Wl,-znorelro']), (1, executable + ': failed PIE RELRO Canary')) self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack', '-fstack-protector-all', '-Wl,-znorelro']), (1, executable + ': failed PIE RELRO')) self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack', '-fstack-protector-all', '-Wl,-znorelro', '-pie', '-fPIE']), (1, executable + ': failed RELRO')) self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-znoexecstack', '-fstack-protector-all', '-Wl,-zrelro', '-Wl,-z,now', '-pie', '-fPIE']), (0, '')) - def test_PE(self): + def test_32bit_PE(self): source = 'test1.c' executable = 'test1.exe' cc = 'i686-w64-mingw32-gcc' write_testcode(source) self.assertEqual(call_security_check(cc, source, executable, []), - (1, executable + ': failed PIE NX')) + (1, executable + ': failed DYNAMIC_BASE NX')) self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat']), - (1, executable + ': failed PIE')) + (1, executable + ': failed DYNAMIC_BASE')) self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat', '-Wl,--dynamicbase']), (0, '')) + def test_64bit_PE(self): + source = 'test1.c' + executable = 'test1.exe' + cc = 'x86_64-w64-mingw32-gcc' + write_testcode(source) + + self.assertEqual( + call_security_check( + cc, + source, + executable, + []), + (1, + executable + ': failed DYNAMIC_BASE NX\n' + executable + ': warning HIGH_ENTROPY_VA')) + self.assertEqual( + call_security_check( + cc, + source, + executable, + ['-Wl,--nxcompat']), + (1, + executable + ': failed DYNAMIC_BASE\n' + executable + ': warning HIGH_ENTROPY_VA')) + self.assertEqual( + call_security_check( + cc, source, executable, [ + '-Wl,--nxcompat', '-Wl,--dynamicbase']), (0, executable + ': warning HIGH_ENTROPY_VA')) + self.assertEqual( + call_security_check( + cc, source, executable, [ + '-Wl,--nxcompat', '-Wl,--dynamicbase', '-Wl,--high-entropy-va']), (0, '')) + if __name__ == '__main__': unittest.main()