mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 12:02:48 +01:00
partial bitcoin#22381: Test security-check sanity before performing them (with macOS)
excludes: - d6ef3543ae16847d5a91fa9271acee9bd2164b32
This commit is contained in:
parent
d4a8d49e56
commit
24a6642b6f
13
Makefile.am
13
Makefile.am
@ -57,6 +57,7 @@ DIST_SHARE = \
|
|||||||
|
|
||||||
BIN_CHECKS=$(top_srcdir)/contrib/devtools/symbol-check.py \
|
BIN_CHECKS=$(top_srcdir)/contrib/devtools/symbol-check.py \
|
||||||
$(top_srcdir)/contrib/devtools/security-check.py \
|
$(top_srcdir)/contrib/devtools/security-check.py \
|
||||||
|
$(top_srcdir)/contrib/devtools/utils.py \
|
||||||
$(top_srcdir)/contrib/devtools/pixie.py
|
$(top_srcdir)/contrib/devtools/pixie.py
|
||||||
|
|
||||||
WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/dash.ico \
|
WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/dash.ico \
|
||||||
@ -342,14 +343,14 @@ clean-local: clean-docs
|
|||||||
|
|
||||||
test-security-check:
|
test-security-check:
|
||||||
if TARGET_DARWIN
|
if TARGET_DARWIN
|
||||||
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_MACHO
|
$(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_MACHO
|
||||||
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_MACHO
|
$(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_MACHO
|
||||||
endif
|
endif
|
||||||
if TARGET_WINDOWS
|
if TARGET_WINDOWS
|
||||||
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_PE
|
$(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_PE
|
||||||
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_PE
|
$(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_PE
|
||||||
endif
|
endif
|
||||||
if TARGET_LINUX
|
if TARGET_LINUX
|
||||||
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_ELF
|
$(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_ELF
|
||||||
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_ELF
|
$(AM_V_at) CC='$(CC)' CPPFILT='$(CPPFILT)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_ELF
|
||||||
endif
|
endif
|
||||||
|
@ -942,6 +942,7 @@ if test x$use_hardening != xno; then
|
|||||||
])
|
])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AX_CHECK_LINK_FLAG([[-Wl,--enable-reloc-section]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--enable-reloc-section"],, [[$LDFLAG_WERROR]])
|
||||||
AX_CHECK_LINK_FLAG([[-Wl,--dynamicbase]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--dynamicbase"])
|
AX_CHECK_LINK_FLAG([[-Wl,--dynamicbase]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--dynamicbase"])
|
||||||
AX_CHECK_LINK_FLAG([[-Wl,--nxcompat]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--nxcompat"])
|
AX_CHECK_LINK_FLAG([[-Wl,--nxcompat]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--nxcompat"])
|
||||||
AX_CHECK_LINK_FLAG([[-Wl,--high-entropy-va]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--high-entropy-va"])
|
AX_CHECK_LINK_FLAG([[-Wl,--high-entropy-va]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--high-entropy-va"])
|
||||||
|
@ -12,12 +12,13 @@ Example usage:
|
|||||||
'''
|
'''
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import os
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import lief
|
import lief
|
||||||
import pixie
|
import pixie
|
||||||
|
|
||||||
|
from utils import determine_wellknown_cmd
|
||||||
|
|
||||||
# Debian 9 (Stretch) EOL: 2022. https://wiki.debian.org/DebianReleases#Production_Releases
|
# Debian 9 (Stretch) EOL: 2022. https://wiki.debian.org/DebianReleases#Production_Releases
|
||||||
#
|
#
|
||||||
# - g++ version 6.3.0 (https://packages.debian.org/search?suite=stretch&arch=any&searchon=names&keywords=g%2B%2B)
|
# - g++ version 6.3.0 (https://packages.debian.org/search?suite=stretch&arch=any&searchon=names&keywords=g%2B%2B)
|
||||||
@ -64,7 +65,6 @@ IGNORE_EXPORTS = {
|
|||||||
# Used in stacktraces.cpp
|
# Used in stacktraces.cpp
|
||||||
'__cxa_demangle'
|
'__cxa_demangle'
|
||||||
}
|
}
|
||||||
CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt')
|
|
||||||
|
|
||||||
# Allowed NEEDED libraries
|
# Allowed NEEDED libraries
|
||||||
ELF_ALLOWED_LIBRARIES = {
|
ELF_ALLOWED_LIBRARIES = {
|
||||||
@ -147,7 +147,7 @@ class CPPFilt(object):
|
|||||||
Use a pipe to the 'c++filt' command.
|
Use a pipe to the 'c++filt' command.
|
||||||
'''
|
'''
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.proc = subprocess.Popen(CPPFILT_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True)
|
self.proc = subprocess.Popen(determine_wellknown_cmd('CPPFILT', 'c++filt'), stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True)
|
||||||
|
|
||||||
def __call__(self, mangled):
|
def __call__(self, mangled):
|
||||||
self.proc.stdin.write(mangled + '\n')
|
self.proc.stdin.write(mangled + '\n')
|
||||||
|
@ -9,6 +9,8 @@ import os
|
|||||||
import subprocess
|
import subprocess
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
from utils import determine_wellknown_cmd
|
||||||
|
|
||||||
def write_testcode(filename):
|
def write_testcode(filename):
|
||||||
with open(filename, 'w', encoding="utf8") as f:
|
with open(filename, 'w', encoding="utf8") as f:
|
||||||
f.write('''
|
f.write('''
|
||||||
@ -25,7 +27,7 @@ def clean_files(source, executable):
|
|||||||
os.remove(executable)
|
os.remove(executable)
|
||||||
|
|
||||||
def call_security_check(cc, source, executable, options):
|
def call_security_check(cc, source, executable, options):
|
||||||
subprocess.run([cc,source,'-o',executable] + options, check=True)
|
subprocess.run([*cc,source,'-o',executable] + options, check=True)
|
||||||
p = subprocess.run(['./contrib/devtools/security-check.py',executable], stdout=subprocess.PIPE, universal_newlines=True)
|
p = subprocess.run(['./contrib/devtools/security-check.py',executable], stdout=subprocess.PIPE, universal_newlines=True)
|
||||||
return (p.returncode, p.stdout.rstrip())
|
return (p.returncode, p.stdout.rstrip())
|
||||||
|
|
||||||
@ -33,7 +35,7 @@ class TestSecurityChecks(unittest.TestCase):
|
|||||||
def test_ELF(self):
|
def test_ELF(self):
|
||||||
source = 'test1.c'
|
source = 'test1.c'
|
||||||
executable = 'test1'
|
executable = 'test1'
|
||||||
cc = 'gcc'
|
cc = determine_wellknown_cmd('CC', 'gcc')
|
||||||
write_testcode(source)
|
write_testcode(source)
|
||||||
|
|
||||||
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-zexecstack','-fno-stack-protector','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']),
|
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-zexecstack','-fno-stack-protector','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']),
|
||||||
@ -54,18 +56,20 @@ class TestSecurityChecks(unittest.TestCase):
|
|||||||
def test_PE(self):
|
def test_PE(self):
|
||||||
source = 'test1.c'
|
source = 'test1.c'
|
||||||
executable = 'test1.exe'
|
executable = 'test1.exe'
|
||||||
cc = 'x86_64-w64-mingw32-gcc'
|
cc = determine_wellknown_cmd('CC', 'x86_64-w64-mingw32-gcc')
|
||||||
write_testcode(source)
|
write_testcode(source)
|
||||||
|
|
||||||
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--no-nxcompat','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']),
|
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--no-nxcompat','-Wl,--disable-reloc-section','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']),
|
||||||
(1, executable+': failed DYNAMIC_BASE HIGH_ENTROPY_VA NX RELOC_SECTION'))
|
(1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA NX RELOC_SECTION'))
|
||||||
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']),
|
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--disable-reloc-section','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']),
|
||||||
(1, executable+': failed DYNAMIC_BASE HIGH_ENTROPY_VA RELOC_SECTION'))
|
(1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA RELOC_SECTION'))
|
||||||
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']),
|
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']),
|
||||||
(1, executable+': failed HIGH_ENTROPY_VA RELOC_SECTION'))
|
(1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA'))
|
||||||
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--dynamicbase','-Wl,--high-entropy-va','-no-pie','-fno-PIE']),
|
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-pie','-fPIE']),
|
||||||
(1, executable+': failed RELOC_SECTION'))
|
(1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA')) # -pie -fPIE does nothing unless --dynamicbase is also supplied
|
||||||
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--dynamicbase','-Wl,--high-entropy-va','-pie','-fPIE']),
|
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--dynamicbase','-Wl,--no-high-entropy-va','-pie','-fPIE']),
|
||||||
|
(1, executable+': failed HIGH_ENTROPY_VA'))
|
||||||
|
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--dynamicbase','-Wl,--high-entropy-va','-pie','-fPIE']),
|
||||||
(0, ''))
|
(0, ''))
|
||||||
|
|
||||||
clean_files(source, executable)
|
clean_files(source, executable)
|
||||||
@ -73,7 +77,7 @@ class TestSecurityChecks(unittest.TestCase):
|
|||||||
def test_MACHO(self):
|
def test_MACHO(self):
|
||||||
source = 'test1.c'
|
source = 'test1.c'
|
||||||
executable = 'test1'
|
executable = 'test1'
|
||||||
cc = 'clang'
|
cc = determine_wellknown_cmd('CC', 'clang')
|
||||||
write_testcode(source)
|
write_testcode(source)
|
||||||
|
|
||||||
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fno-stack-protector']),
|
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fno-stack-protector']),
|
||||||
@ -93,4 +97,3 @@ class TestSecurityChecks(unittest.TestCase):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
||||||
|
@ -7,41 +7,51 @@ Test script for symbol-check.py
|
|||||||
'''
|
'''
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from typing import List
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
def call_symbol_check(cc, source, executable, options):
|
from utils import determine_wellknown_cmd
|
||||||
subprocess.run([cc,source,'-o',executable] + options, check=True)
|
|
||||||
|
def call_symbol_check(cc: List[str], source, executable, options):
|
||||||
|
subprocess.run([*cc,source,'-o',executable] + options, check=True)
|
||||||
p = subprocess.run(['./contrib/devtools/symbol-check.py',executable], stdout=subprocess.PIPE, universal_newlines=True)
|
p = subprocess.run(['./contrib/devtools/symbol-check.py',executable], stdout=subprocess.PIPE, universal_newlines=True)
|
||||||
os.remove(source)
|
os.remove(source)
|
||||||
os.remove(executable)
|
os.remove(executable)
|
||||||
return (p.returncode, p.stdout.rstrip())
|
return (p.returncode, p.stdout.rstrip())
|
||||||
|
|
||||||
|
def get_machine(cc: List[str]):
|
||||||
|
p = subprocess.run([*cc,'-dumpmachine'], stdout=subprocess.PIPE, universal_newlines=True)
|
||||||
|
return p.stdout.rstrip()
|
||||||
|
|
||||||
class TestSymbolChecks(unittest.TestCase):
|
class TestSymbolChecks(unittest.TestCase):
|
||||||
def test_ELF(self):
|
def test_ELF(self):
|
||||||
source = 'test1.c'
|
source = 'test1.c'
|
||||||
executable = 'test1'
|
executable = 'test1'
|
||||||
cc = 'gcc'
|
cc = determine_wellknown_cmd('CC', 'gcc')
|
||||||
|
|
||||||
# renameat2 was introduced in GLIBC 2.28, so is newer than the upper limit
|
# there's no way to do this test for RISC-V at the moment; we build for
|
||||||
# of glibc for all platforms
|
# RISC-V in a glibc 2.27 envinonment and we allow all symbols from 2.27.
|
||||||
|
if 'riscv' in get_machine(cc):
|
||||||
|
self.skipTest("test not available for RISC-V")
|
||||||
|
|
||||||
|
# nextup was introduced in GLIBC 2.24, so is newer than our supported
|
||||||
|
# glibc (2.17), and available in our release build environment (2.24).
|
||||||
with open(source, 'w', encoding="utf8") as f:
|
with open(source, 'w', encoding="utf8") as f:
|
||||||
f.write('''
|
f.write('''
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <stdio.h>
|
#include <math.h>
|
||||||
#include <linux/fs.h>
|
|
||||||
|
|
||||||
int renameat2(int olddirfd, const char *oldpath,
|
double nextup(double x);
|
||||||
int newdirfd, const char *newpath, unsigned int flags);
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
renameat2(0, "test", 0, "test_", RENAME_EXCHANGE);
|
nextup(3.14);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
''')
|
''')
|
||||||
|
|
||||||
self.assertEqual(call_symbol_check(cc, source, executable, []),
|
self.assertEqual(call_symbol_check(cc, source, executable, ['-lm']),
|
||||||
(1, executable + ': symbol renameat2 from unsupported version GLIBC_2.28\n' +
|
(1, executable + ': symbol nextup from unsupported version GLIBC_2.24\n' +
|
||||||
executable + ': failed IMPORTED_SYMBOLS'))
|
executable + ': failed IMPORTED_SYMBOLS'))
|
||||||
|
|
||||||
# -lutil is part of the libc6 package so a safe bet that it's installed
|
# -lutil is part of the libc6 package so a safe bet that it's installed
|
||||||
@ -83,7 +93,7 @@ class TestSymbolChecks(unittest.TestCase):
|
|||||||
def test_MACHO(self):
|
def test_MACHO(self):
|
||||||
source = 'test1.c'
|
source = 'test1.c'
|
||||||
executable = 'test1'
|
executable = 'test1'
|
||||||
cc = 'clang'
|
cc = determine_wellknown_cmd('CC', 'clang')
|
||||||
|
|
||||||
with open(source, 'w', encoding="utf8") as f:
|
with open(source, 'w', encoding="utf8") as f:
|
||||||
f.write('''
|
f.write('''
|
||||||
@ -97,7 +107,7 @@ class TestSymbolChecks(unittest.TestCase):
|
|||||||
|
|
||||||
''')
|
''')
|
||||||
|
|
||||||
self.assertEqual(call_symbol_check(cc, source, executable, ['-lexpat']),
|
self.assertEqual(call_symbol_check(cc, source, executable, ['-lexpat', '-Wl,-platform_version','-Wl,macos', '-Wl,11.4', '-Wl,11.4']),
|
||||||
(1, 'libexpat.1.dylib is not in ALLOWED_LIBRARIES!\n' +
|
(1, 'libexpat.1.dylib is not in ALLOWED_LIBRARIES!\n' +
|
||||||
f'{executable}: failed DYNAMIC_LIBRARIES MIN_OS SDK'))
|
f'{executable}: failed DYNAMIC_LIBRARIES MIN_OS SDK'))
|
||||||
|
|
||||||
@ -114,7 +124,7 @@ class TestSymbolChecks(unittest.TestCase):
|
|||||||
}
|
}
|
||||||
''')
|
''')
|
||||||
|
|
||||||
self.assertEqual(call_symbol_check(cc, source, executable, ['-framework', 'CoreGraphics']),
|
self.assertEqual(call_symbol_check(cc, source, executable, ['-framework', 'CoreGraphics', '-Wl,-platform_version','-Wl,macos', '-Wl,11.4', '-Wl,11.4']),
|
||||||
(1, f'{executable}: failed MIN_OS SDK'))
|
(1, f'{executable}: failed MIN_OS SDK'))
|
||||||
|
|
||||||
source = 'test3.c'
|
source = 'test3.c'
|
||||||
@ -127,13 +137,13 @@ class TestSymbolChecks(unittest.TestCase):
|
|||||||
}
|
}
|
||||||
''')
|
''')
|
||||||
|
|
||||||
self.assertEqual(call_symbol_check(cc, source, executable, ['-mmacosx-version-min=10.14']),
|
self.assertEqual(call_symbol_check(cc, source, executable, ['-Wl,-platform_version','-Wl,macos', '-Wl,10.15', '-Wl,11.4']),
|
||||||
(1, f'{executable}: failed SDK'))
|
(1, f'{executable}: failed SDK'))
|
||||||
|
|
||||||
def test_PE(self):
|
def test_PE(self):
|
||||||
source = 'test1.c'
|
source = 'test1.c'
|
||||||
executable = 'test1.exe'
|
executable = 'test1.exe'
|
||||||
cc = 'x86_64-w64-mingw32-gcc'
|
cc = determine_wellknown_cmd('CC', 'x86_64-w64-mingw32-gcc')
|
||||||
|
|
||||||
with open(source, 'w', encoding="utf8") as f:
|
with open(source, 'w', encoding="utf8") as f:
|
||||||
f.write('''
|
f.write('''
|
||||||
@ -183,4 +193,3 @@ class TestSymbolChecks(unittest.TestCase):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
||||||
|
22
contrib/devtools/utils.py
Executable file
22
contrib/devtools/utils.py
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# Copyright (c) 2021 The Bitcoin Core developers
|
||||||
|
# Distributed under the MIT software license, see the accompanying
|
||||||
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
'''
|
||||||
|
Common utility functions
|
||||||
|
'''
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
|
||||||
|
def determine_wellknown_cmd(envvar, progname) -> List[str]:
|
||||||
|
maybe_env = os.getenv(envvar)
|
||||||
|
maybe_which = shutil.which(progname)
|
||||||
|
if maybe_env:
|
||||||
|
return maybe_env.split(' ') # Well-known vars are often meant to be word-split
|
||||||
|
elif maybe_which:
|
||||||
|
return [ maybe_which ]
|
||||||
|
else:
|
||||||
|
sys.exit(f"{progname} not found")
|
@ -295,10 +295,11 @@ mkdir -p "$DISTSRC"
|
|||||||
# Build Dash Core
|
# Build Dash Core
|
||||||
make --jobs="$JOBS" ${V:+V=1}
|
make --jobs="$JOBS" ${V:+V=1}
|
||||||
|
|
||||||
# Perform basic ELF security checks on a series of executables.
|
# Check that symbol/security checks tools are sane.
|
||||||
|
make test-security-check ${V:+V=1}
|
||||||
|
# Perform basic security checks on a series of executables.
|
||||||
make -C src --jobs=1 check-security ${V:+V=1}
|
make -C src --jobs=1 check-security ${V:+V=1}
|
||||||
# Check that executables only contain allowed gcc, glibc and libstdc++
|
# Check that executables only contain allowed version symbols.
|
||||||
# version symbols for Linux distro back-compatibility.
|
|
||||||
make -C src --jobs=1 check-symbols ${V:+V=1}
|
make -C src --jobs=1 check-symbols ${V:+V=1}
|
||||||
|
|
||||||
mkdir -p "$OUTDIR"
|
mkdir -p "$OUTDIR"
|
||||||
|
@ -85,6 +85,10 @@ http://www.linuxfromscratch.org/hlfs/view/development/chapter05/gcc-pass1.html"
|
|||||||
(define (explicit-cross-configure package)
|
(define (explicit-cross-configure package)
|
||||||
(package-with-extra-configure-variable package "--build" building-on))
|
(package-with-extra-configure-variable package "--build" building-on))
|
||||||
|
|
||||||
|
(define (make-binutils-with-mingw-w64-disable-flags xbinutils)
|
||||||
|
(package-with-extra-patches xbinutils
|
||||||
|
(search-our-patches "binutils-mingw-w64-disable-flags.patch")))
|
||||||
|
|
||||||
(define (make-cross-toolchain target
|
(define (make-cross-toolchain target
|
||||||
base-gcc-for-libc
|
base-gcc-for-libc
|
||||||
base-kernel-headers
|
base-kernel-headers
|
||||||
@ -173,7 +177,7 @@ desirable for building Dash Core release binaries."
|
|||||||
|
|
||||||
(define (make-mingw-pthreads-cross-toolchain target)
|
(define (make-mingw-pthreads-cross-toolchain target)
|
||||||
"Create a cross-compilation toolchain package for TARGET"
|
"Create a cross-compilation toolchain package for TARGET"
|
||||||
(let* ((xbinutils (cross-binutils target))
|
(let* ((xbinutils (make-binutils-with-mingw-w64-disable-flags (cross-binutils target)))
|
||||||
(pthreads-xlibc mingw-w64-x86_64-winpthreads)
|
(pthreads-xlibc mingw-w64-x86_64-winpthreads)
|
||||||
(pthreads-xgcc (make-gcc-with-pthreads
|
(pthreads-xgcc (make-gcc-with-pthreads
|
||||||
(cross-gcc target
|
(cross-gcc target
|
||||||
|
171
contrib/guix/patches/binutils-mingw-w64-disable-flags.patch
Normal file
171
contrib/guix/patches/binutils-mingw-w64-disable-flags.patch
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
Description: Add disable opposites to the security-related flags
|
||||||
|
Author: Stephen Kitt <skitt@debian.org>
|
||||||
|
|
||||||
|
This patch adds "no-" variants to disable the various security flags:
|
||||||
|
"no-dynamicbase", "no-nxcompat", "no-high-entropy-va", "disable-reloc-section".
|
||||||
|
|
||||||
|
--- a/ld/emultempl/pe.em
|
||||||
|
+++ b/ld/emultempl/pe.em
|
||||||
|
@@ -259,9 +261,11 @@
|
||||||
|
(OPTION_ENABLE_LONG_SECTION_NAMES + 1)
|
||||||
|
/* DLLCharacteristics flags. */
|
||||||
|
#define OPTION_DYNAMIC_BASE (OPTION_DISABLE_LONG_SECTION_NAMES + 1)
|
||||||
|
-#define OPTION_FORCE_INTEGRITY (OPTION_DYNAMIC_BASE + 1)
|
||||||
|
+#define OPTION_NO_DYNAMIC_BASE (OPTION_DYNAMIC_BASE + 1)
|
||||||
|
+#define OPTION_FORCE_INTEGRITY (OPTION_NO_DYNAMIC_BASE + 1)
|
||||||
|
#define OPTION_NX_COMPAT (OPTION_FORCE_INTEGRITY + 1)
|
||||||
|
-#define OPTION_NO_ISOLATION (OPTION_NX_COMPAT + 1)
|
||||||
|
+#define OPTION_NO_NX_COMPAT (OPTION_NX_COMPAT + 1)
|
||||||
|
+#define OPTION_NO_ISOLATION (OPTION_NO_NX_COMPAT + 1)
|
||||||
|
#define OPTION_NO_SEH (OPTION_NO_ISOLATION + 1)
|
||||||
|
#define OPTION_NO_BIND (OPTION_NO_SEH + 1)
|
||||||
|
#define OPTION_WDM_DRIVER (OPTION_NO_BIND + 1)
|
||||||
|
@@ -271,6 +275,7 @@
|
||||||
|
#define OPTION_NO_INSERT_TIMESTAMP (OPTION_INSERT_TIMESTAMP + 1)
|
||||||
|
#define OPTION_BUILD_ID (OPTION_NO_INSERT_TIMESTAMP + 1)
|
||||||
|
#define OPTION_ENABLE_RELOC_SECTION (OPTION_BUILD_ID + 1)
|
||||||
|
+#define OPTION_DISABLE_RELOC_SECTION (OPTION_ENABLE_RELOC_SECTION + 1)
|
||||||
|
|
||||||
|
static void
|
||||||
|
gld${EMULATION_NAME}_add_options
|
||||||
|
@@ -342,8 +347,10 @@
|
||||||
|
{"enable-long-section-names", no_argument, NULL, OPTION_ENABLE_LONG_SECTION_NAMES},
|
||||||
|
{"disable-long-section-names", no_argument, NULL, OPTION_DISABLE_LONG_SECTION_NAMES},
|
||||||
|
{"dynamicbase",no_argument, NULL, OPTION_DYNAMIC_BASE},
|
||||||
|
+ {"no-dynamicbase", no_argument, NULL, OPTION_NO_DYNAMIC_BASE},
|
||||||
|
{"forceinteg", no_argument, NULL, OPTION_FORCE_INTEGRITY},
|
||||||
|
{"nxcompat", no_argument, NULL, OPTION_NX_COMPAT},
|
||||||
|
+ {"no-nxcompat", no_argument, NULL, OPTION_NO_NX_COMPAT},
|
||||||
|
{"no-isolation", no_argument, NULL, OPTION_NO_ISOLATION},
|
||||||
|
{"no-seh", no_argument, NULL, OPTION_NO_SEH},
|
||||||
|
{"no-bind", no_argument, NULL, OPTION_NO_BIND},
|
||||||
|
@@ -351,6 +358,7 @@
|
||||||
|
{"tsaware", no_argument, NULL, OPTION_TERMINAL_SERVER_AWARE},
|
||||||
|
{"build-id", optional_argument, NULL, OPTION_BUILD_ID},
|
||||||
|
{"enable-reloc-section", no_argument, NULL, OPTION_ENABLE_RELOC_SECTION},
|
||||||
|
+ {"disable-reloc-section", no_argument, NULL, OPTION_DISABLE_RELOC_SECTION},
|
||||||
|
{NULL, no_argument, NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -485,9 +494,12 @@
|
||||||
|
in object files\n"));
|
||||||
|
fprintf (file, _(" --dynamicbase Image base address may be relocated using\n\
|
||||||
|
address space layout randomization (ASLR)\n"));
|
||||||
|
+ fprintf (file, _(" --no-dynamicbase Image base address may not be relocated\n"));
|
||||||
|
fprintf (file, _(" --enable-reloc-section Create the base relocation table\n"));
|
||||||
|
+ fprintf (file, _(" --disable-reloc-section Disable the base relocation table\n"));
|
||||||
|
fprintf (file, _(" --forceinteg Code integrity checks are enforced\n"));
|
||||||
|
fprintf (file, _(" --nxcompat Image is compatible with data execution prevention\n"));
|
||||||
|
+ fprintf (file, _(" --no-nxcompat Image is not compatible with data execution prevention\n"));
|
||||||
|
fprintf (file, _(" --no-isolation Image understands isolation but do not isolate the image\n"));
|
||||||
|
fprintf (file, _(" --no-seh Image does not use SEH. No SE handler may\n\
|
||||||
|
be called in this image\n"));
|
||||||
|
@@ -862,12 +874,21 @@
|
||||||
|
case OPTION_ENABLE_RELOC_SECTION:
|
||||||
|
pe_dll_enable_reloc_section = 1;
|
||||||
|
break;
|
||||||
|
+ case OPTION_DISABLE_RELOC_SECTION:
|
||||||
|
+ pe_dll_enable_reloc_section = 0;
|
||||||
|
+ /* fall through */
|
||||||
|
+ case OPTION_NO_DYNAMIC_BASE:
|
||||||
|
+ pe_dll_characteristics &= ~IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
|
||||||
|
+ break;
|
||||||
|
case OPTION_FORCE_INTEGRITY:
|
||||||
|
pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY;
|
||||||
|
break;
|
||||||
|
case OPTION_NX_COMPAT:
|
||||||
|
pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
|
||||||
|
break;
|
||||||
|
+ case OPTION_NO_NX_COMPAT:
|
||||||
|
+ pe_dll_characteristics &= ~IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
|
||||||
|
+ break;
|
||||||
|
case OPTION_NO_ISOLATION:
|
||||||
|
pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_NO_ISOLATION;
|
||||||
|
break;
|
||||||
|
--- a/ld/emultempl/pep.em
|
||||||
|
+++ b/ld/emultempl/pep.em
|
||||||
|
@@ -237,9 +240,12 @@
|
||||||
|
OPTION_ENABLE_LONG_SECTION_NAMES,
|
||||||
|
OPTION_DISABLE_LONG_SECTION_NAMES,
|
||||||
|
OPTION_HIGH_ENTROPY_VA,
|
||||||
|
+ OPTION_NO_HIGH_ENTROPY_VA,
|
||||||
|
OPTION_DYNAMIC_BASE,
|
||||||
|
+ OPTION_NO_DYNAMIC_BASE,
|
||||||
|
OPTION_FORCE_INTEGRITY,
|
||||||
|
OPTION_NX_COMPAT,
|
||||||
|
+ OPTION_NO_NX_COMPAT,
|
||||||
|
OPTION_NO_ISOLATION,
|
||||||
|
OPTION_NO_SEH,
|
||||||
|
OPTION_NO_BIND,
|
||||||
|
@@ -248,7 +254,8 @@
|
||||||
|
OPTION_NO_INSERT_TIMESTAMP,
|
||||||
|
OPTION_TERMINAL_SERVER_AWARE,
|
||||||
|
OPTION_BUILD_ID,
|
||||||
|
- OPTION_ENABLE_RELOC_SECTION
|
||||||
|
+ OPTION_ENABLE_RELOC_SECTION,
|
||||||
|
+ OPTION_DISABLE_RELOC_SECTION
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -315,9 +322,12 @@
|
||||||
|
{"enable-long-section-names", no_argument, NULL, OPTION_ENABLE_LONG_SECTION_NAMES},
|
||||||
|
{"disable-long-section-names", no_argument, NULL, OPTION_DISABLE_LONG_SECTION_NAMES},
|
||||||
|
{"high-entropy-va", no_argument, NULL, OPTION_HIGH_ENTROPY_VA},
|
||||||
|
+ {"no-high-entropy-va", no_argument, NULL, OPTION_NO_HIGH_ENTROPY_VA},
|
||||||
|
{"dynamicbase",no_argument, NULL, OPTION_DYNAMIC_BASE},
|
||||||
|
+ {"no-dynamicbase", no_argument, NULL, OPTION_NO_DYNAMIC_BASE},
|
||||||
|
{"forceinteg", no_argument, NULL, OPTION_FORCE_INTEGRITY},
|
||||||
|
{"nxcompat", no_argument, NULL, OPTION_NX_COMPAT},
|
||||||
|
+ {"no-nxcompat", no_argument, NULL, OPTION_NO_NX_COMPAT},
|
||||||
|
{"no-isolation", no_argument, NULL, OPTION_NO_ISOLATION},
|
||||||
|
{"no-seh", no_argument, NULL, OPTION_NO_SEH},
|
||||||
|
{"no-bind", no_argument, NULL, OPTION_NO_BIND},
|
||||||
|
@@ -327,6 +337,7 @@
|
||||||
|
{"no-insert-timestamp", no_argument, NULL, OPTION_NO_INSERT_TIMESTAMP},
|
||||||
|
{"build-id", optional_argument, NULL, OPTION_BUILD_ID},
|
||||||
|
{"enable-reloc-section", no_argument, NULL, OPTION_ENABLE_RELOC_SECTION},
|
||||||
|
+ {"disable-reloc-section", no_argument, NULL, OPTION_DISABLE_RELOC_SECTION},
|
||||||
|
{NULL, no_argument, NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -448,11 +461,15 @@
|
||||||
|
in object files\n"));
|
||||||
|
fprintf (file, _(" --high-entropy-va Image is compatible with 64-bit address space\n\
|
||||||
|
layout randomization (ASLR)\n"));
|
||||||
|
+ fprintf (file, _(" --no-high-entropy-va Image is not compatible with 64-bit ASLR\n"));
|
||||||
|
fprintf (file, _(" --dynamicbase Image base address may be relocated using\n\
|
||||||
|
address space layout randomization (ASLR)\n"));
|
||||||
|
+ fprintf (file, _(" --no-dynamicbase Image base address may not be relocated\n"));
|
||||||
|
fprintf (file, _(" --enable-reloc-section Create the base relocation table\n"));
|
||||||
|
+ fprintf (file, _(" --disable-reloc-section Disable the base relocation table\n"));
|
||||||
|
fprintf (file, _(" --forceinteg Code integrity checks are enforced\n"));
|
||||||
|
fprintf (file, _(" --nxcompat Image is compatible with data execution prevention\n"));
|
||||||
|
+ fprintf (file, _(" --no-nxcompat Image is not compatible with data execution prevention\n"));
|
||||||
|
fprintf (file, _(" --no-isolation Image understands isolation but do not isolate the image\n"));
|
||||||
|
fprintf (file, _(" --no-seh Image does not use SEH; no SE handler may\n\
|
||||||
|
be called in this image\n"));
|
||||||
|
@@ -809,12 +826,24 @@
|
||||||
|
case OPTION_ENABLE_RELOC_SECTION:
|
||||||
|
pep_dll_enable_reloc_section = 1;
|
||||||
|
break;
|
||||||
|
+ case OPTION_DISABLE_RELOC_SECTION:
|
||||||
|
+ pep_dll_enable_reloc_section = 0;
|
||||||
|
+ /* fall through */
|
||||||
|
+ case OPTION_NO_DYNAMIC_BASE:
|
||||||
|
+ pe_dll_characteristics &= ~IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
|
||||||
|
+ /* fall through */
|
||||||
|
+ case OPTION_NO_HIGH_ENTROPY_VA:
|
||||||
|
+ pe_dll_characteristics &= ~IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA;
|
||||||
|
+ break;
|
||||||
|
case OPTION_FORCE_INTEGRITY:
|
||||||
|
pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY;
|
||||||
|
break;
|
||||||
|
case OPTION_NX_COMPAT:
|
||||||
|
pe_dll_characteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
|
||||||
|
break;
|
||||||
|
+ case OPTION_NO_NX_COMPAT:
|
||||||
|
+ pe_dll_characteristics &= ~IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
|
||||||
|
+ break;
|
||||||
|
case OPTION_NO_ISOLATION:
|
||||||
|
pe_dll_characteristics |= IMAGE_DLLCHARACTERISTICS_NO_ISOLATION;
|
||||||
|
break;
|
@ -935,23 +935,23 @@ clean-local:
|
|||||||
check-symbols: $(bin_PROGRAMS)
|
check-symbols: $(bin_PROGRAMS)
|
||||||
if TARGET_DARWIN
|
if TARGET_DARWIN
|
||||||
@echo "Checking macOS dynamic libraries..."
|
@echo "Checking macOS dynamic libraries..."
|
||||||
$(AM_V_at) OTOOL=$(OTOOL) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
|
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if TARGET_WINDOWS
|
if TARGET_WINDOWS
|
||||||
@echo "Checking Windows dynamic libraries..."
|
@echo "Checking Windows dynamic libraries..."
|
||||||
$(AM_V_at) OBJDUMP=$(OBJDUMP) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
|
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if GLIBC_BACK_COMPAT
|
if GLIBC_BACK_COMPAT
|
||||||
@echo "Checking glibc back compat..."
|
@echo "Checking glibc back compat..."
|
||||||
$(AM_V_at) CPPFILT=$(CPPFILT) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
|
$(AM_V_at) CPPFILT='$(CPPFILT)' $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
check-security: $(bin_PROGRAMS)
|
check-security: $(bin_PROGRAMS)
|
||||||
if HARDEN
|
if HARDEN
|
||||||
@echo "Checking binary security..."
|
@echo "Checking binary security..."
|
||||||
$(AM_V_at) OBJDUMP=$(OBJDUMP) OTOOL=$(OTOOL) $(PYTHON) $(top_srcdir)/contrib/devtools/security-check.py $(bin_PROGRAMS)
|
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/security-check.py $(bin_PROGRAMS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user