diff --git a/Makefile.am b/Makefile.am index 8124d7909a1f..ea2cba9fd2fa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -53,8 +53,8 @@ DIST_SHARE = \ $(top_srcdir)/share/genbuild.sh \ $(top_srcdir)/share/rpcauth -BIN_CHECKS=$(top_srcdir)/contrib/devtools/symbol-check.py \ - $(top_srcdir)/contrib/devtools/security-check.py \ +BIN_CHECKS=$(top_srcdir)/contrib/guix/symbol-check.py \ + $(top_srcdir)/contrib/guix/security-check.py \ $(top_srcdir)/contrib/devtools/utils.py WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/dash.ico \ @@ -321,17 +321,3 @@ clean-local: clean-docs rm -rf coverage_percent.txt test_dash.coverage/ total.coverage/ fuzz.coverage/ test/tmp/ cache/ $(OSX_APP) rm -rf test/functional/__pycache__ test/functional/test_framework/__pycache__ test/cache share/rpcauth/__pycache__ rm -rf dist/ - -test-security-check: -if TARGET_DARWIN - $(AM_V_at) CXX='$(CXX)' CXXFLAGS='$(CXXFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_MACHO - $(AM_V_at) CXX='$(CXX)' CXXFLAGS='$(CXXFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_MACHO -endif -if TARGET_WINDOWS - $(AM_V_at) CXX='$(CXX)' CXXFLAGS='$(CXXFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_PE - $(AM_V_at) CXX='$(CXX)' CXXFLAGS='$(CXXFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_PE -endif -if TARGET_LINUX - $(AM_V_at) CXX='$(CXX)' CXXFLAGS='$(CXXFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_ELF - $(AM_V_at) CXX='$(CXX)' CXXFLAGS='$(CXXFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_ELF -endif diff --git a/ci/dash/build_src.sh b/ci/dash/build_src.sh index c64f44763d19..391224587271 100755 --- a/ci/dash/build_src.sh +++ b/ci/dash/build_src.sh @@ -57,7 +57,3 @@ fi if [ "${RUN_TIDY}" = "true" ] && [ "${GITHUB_ACTIONS}" != "true" ]; then "${BASE_ROOT_DIR}/ci/dash/lint-tidy.sh" fi - -if [ "$RUN_SECURITY_TESTS" = "true" ]; then - make test-security-check -fi diff --git a/ci/test/00_setup_env.sh b/ci/test/00_setup_env.sh index fc4944ae1d35..4207615a1a94 100755 --- a/ci/test/00_setup_env.sh +++ b/ci/test/00_setup_env.sh @@ -39,7 +39,6 @@ export USE_BUSY_BOX=${USE_BUSY_BOX:-false} export RUN_UNIT_TESTS=${RUN_UNIT_TESTS:-true} export RUN_FUNCTIONAL_TESTS=${RUN_FUNCTIONAL_TESTS:-true} export RUN_TIDY=${RUN_TIDY:-false} -export RUN_SECURITY_TESTS=${RUN_SECURITY_TESTS:-false} # By how much to scale the test_runner timeouts (option --timeout-factor). # This is needed because some ci machines have slow CPU or disk, so sanitizers # might be slow or a reindex might be waiting on disk IO. diff --git a/ci/test/00_setup_env_mac_native_x86_64.sh b/ci/test/00_setup_env_mac_native_x86_64.sh index b20efb2bde37..f38c74603807 100755 --- a/ci/test/00_setup_env_mac_native_x86_64.sh +++ b/ci/test/00_setup_env_mac_native_x86_64.sh @@ -15,5 +15,3 @@ export CI_OS_NAME="macos" export NO_DEPENDS=1 export OSX_SDK="" export CCACHE_MAXSIZE=300M - -export RUN_SECURITY_TESTS="true" diff --git a/ci/test/00_setup_env_win64.sh b/ci/test/00_setup_env_win64.sh index 2010c111818d..74e80dd148eb 100755 --- a/ci/test/00_setup_env_win64.sh +++ b/ci/test/00_setup_env_win64.sh @@ -11,7 +11,6 @@ export HOST=x86_64-w64-mingw32 export DPKG_ADD_ARCH="i386" export PACKAGES="python3 nsis g++-mingw-w64-x86-64-posix wine-binfmt wine64 wine32 file" export RUN_FUNCTIONAL_TESTS=false -export RUN_SECURITY_TESTS="false" export GOAL="deploy" # Prior to 11.0.0, the mingw-w64 headers were missing noreturn attributes, causing warnings when # cross-compiling for Windows. https://sourceforge.net/p/mingw-w64/bugs/306/ diff --git a/configure.ac b/configure.ac index a7fed24bfdbe..94047886c671 100644 --- a/configure.ac +++ b/configure.ac @@ -815,7 +815,7 @@ case $host in AC_MSG_ERROR([windres not found]) fi - CORE_CPPFLAGS="$CORE_CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -D_WIN32_WINNT=0x0601 -D_WIN32_IE=0x0501 -DWIN32_LEAN_AND_MEAN" + CORE_CPPFLAGS="$CORE_CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -D_WIN32_WINNT=0x0A00 -D_WIN32_IE=0x0A00 -DWIN32_LEAN_AND_MEAN" dnl Prevent the definition of min/max macros. dnl We always want to use the standard library. CORE_CPPFLAGS="$CORE_CPPFLAGS -DNOMINMAX" @@ -828,8 +828,10 @@ case $host in archive_cmds_CXX="\$CC -shared \$libobjs \$deplibs \$compiler_flags -static -o \$output_objdir/\$soname \${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker \$lib" postdeps_CXX= - dnl We require Windows 7 (NT 6.1) or later - AX_CHECK_LINK_FLAG([-Wl,--major-subsystem-version -Wl,6 -Wl,--minor-subsystem-version -Wl,1], [CORE_LDFLAGS="$CORE_LDFLAGS -Wl,--major-subsystem-version -Wl,6 -Wl,--minor-subsystem-version -Wl,1"], [], [$LDFLAG_WERROR]) + dnl We support Windows 10+, however it's not possible to set these values accordingly, + dnl due to a bug in mingw-w64. See https://sourceforge.net/p/mingw-w64/bugs/968/. + dnl As a best effort, target Windows 8. + AX_CHECK_LINK_FLAG([-Wl,--major-subsystem-version -Wl,6 -Wl,--minor-subsystem-version -Wl,2], [CORE_LDFLAGS="$CORE_LDFLAGS -Wl,--major-subsystem-version -Wl,6 -Wl,--minor-subsystem-version -Wl,2"], [], [$LDFLAG_WERROR]) dnl Avoid the use of aligned vector instructions when building for Windows. dnl See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54412. @@ -1073,8 +1075,7 @@ if test "$use_hardening" != "no"; then case $host in *mingw*) - dnl stack-clash-protection doesn't compile with GCC 10 and earlier. - dnl In any case, it is a no-op for Windows. + dnl stack-clash-protection is a no-op for Windows. dnl See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90458 for more details. ;; *) @@ -2054,6 +2055,8 @@ AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([doc/Doxyfile])]) AC_CONFIG_LINKS([contrib/filter-lcov.py:contrib/filter-lcov.py]) AC_CONFIG_LINKS([src/.bear-tidy-config:src/.bear-tidy-config]) AC_CONFIG_LINKS([src/.clang-tidy:src/.clang-tidy]) +AC_CONFIG_LINKS([src/ipc/.clang-tidy:src/ipc/.clang-tidy]) +AC_CONFIG_LINKS([src/test/.clang-tidy:src/test/.clang-tidy]) AC_CONFIG_LINKS([test/functional/test_runner.py:test/functional/test_runner.py]) AC_CONFIG_LINKS([test/fuzz/test_runner.py:test/fuzz/test_runner.py]) AC_CONFIG_LINKS([test/util/test_runner.py:test/util/test_runner.py]) diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index 31cc1f032c77..c7dbad85e8be 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -171,35 +171,6 @@ optimize-pngs.py A script to optimize png files in the dash repository (requires pngcrush). -security-check.py and test-security-check.py -============================================ - -Perform basic security checks on a series of executables. - -symbol-check.py -=============== - -A script to check that release executables only contain -certain symbols and are only linked against allowed libraries. - -For Linux this means checking for allowed gcc, glibc and libstdc++ version symbols. -This makes sure they are still compatible with the minimum supported distribution versions. - -For macOS and Windows we check that the executables are only linked against libraries we allow. - -Example usage: - - find ../path/to/executables -type f -executable | xargs python3 contrib/devtools/symbol-check.py - -If no errors occur the return value will be 0 and the output will be empty. - -If there are any errors the return value will be 1 and output like this will be printed: - - .../64/test_dash: symbol memcpy from unsupported version GLIBC_2.14 - .../64/test_dash: symbol __fdelt_chk from unsupported version GLIBC_2.15 - .../64/test_dash: symbol std::out_of_range::~out_of_range() from unsupported version GLIBCXX_3.4.15 - .../64/test_dash: symbol _ZNSt8__detail15_List_nod from unsupported version GLIBCXX_3.4.15 - update-translations.py ====================== diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py deleted file mode 100755 index 74e63f7b465b..000000000000 --- a/contrib/devtools/test-security-check.py +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2015-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. -''' -Test script for security-check.py -''' -import lief -import os -import subprocess -from typing import List -import unittest - -from utils import determine_wellknown_cmd - -def write_testcode(filename): - with open(filename, 'w', encoding="utf8") as f: - f.write(''' - #include - int main() - { - std::printf("the quick brown fox jumps over the lazy god\\n"); - return 0; - } - ''') - -def clean_files(source, executable): - os.remove(source) - os.remove(executable) - -def env_flags() -> List[str]: - # This should behave the same as AC_TRY_LINK, so arrange well-known flags - # in the same order as autoconf would. - # - # See the definitions for ac_link in autoconf's lib/autoconf/c.m4 file for - # reference. - flags: List[str] = [] - for var in ['CXXFLAGS', 'CPPFLAGS', 'LDFLAGS']: - flags += filter(None, os.environ.get(var, '').split(' ')) - return flags - -def call_security_check(cxx, source, executable, options): - subprocess.run([*cxx,source,'-o',executable] + env_flags() + options, check=True) - p = subprocess.run([os.path.join(os.path.dirname(__file__), 'security-check.py'), executable], stdout=subprocess.PIPE, text=True) - return (p.returncode, p.stdout.rstrip()) - -def get_arch(cxx, source, executable): - subprocess.run([*cxx, source, '-o', executable] + env_flags(), check=True) - binary = lief.parse(executable) - arch = binary.abstract.header.architecture - os.remove(executable) - return arch - -class TestSecurityChecks(unittest.TestCase): - def test_ELF(self): - source = 'test1.cpp' - executable = 'test1' - cxx = determine_wellknown_cmd('CXX', 'g++') - write_testcode(source) - arch = get_arch(cxx, source, executable) - - if arch == lief.ARCHITECTURES.X86: - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-zexecstack','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), - (1, executable+': failed PIE NX RELRO CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), - (1, executable+': failed PIE RELRO CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), - (1, executable+': failed PIE RELRO CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-znorelro','-pie','-fPIE', '-Wl,-z,separate-code']), - (1, executable+': failed RELRO CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,noseparate-code']), - (1, executable+': failed separate_code CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,separate-code']), - (1, executable+': failed CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,separate-code', '-fcf-protection=full']), - (0, '')) - else: - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-zexecstack','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), - (1, executable+': failed PIE NX RELRO')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), - (1, executable+': failed PIE RELRO')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']), - (1, executable+': failed PIE RELRO')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-znorelro','-pie','-fPIE', '-Wl,-z,separate-code']), - (1, executable+': failed RELRO')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,noseparate-code']), - (1, executable+': failed separate_code')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-znoexecstack','-Wl,-zrelro','-Wl,-z,now','-pie','-fPIE', '-Wl,-z,separate-code']), - (0, '')) - - clean_files(source, executable) - - def test_PE(self): - source = 'test1.cpp' - executable = 'test1.exe' - cxx = determine_wellknown_cmd('CXX', 'x86_64-w64-mingw32-g++') - write_testcode(source) - - 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']), - (1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA NX RELOC_SECTION CONTROL_FLOW Canary')) - 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']), - (1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA RELOC_SECTION CONTROL_FLOW')) - 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']), - (1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA CONTROL_FLOW')) - 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']), - (1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA CONTROL_FLOW')) # -pie -fPIE does nothing unless --dynamicbase is also supplied - 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']), - (1, executable+': failed HIGH_ENTROPY_VA CONTROL_FLOW')) - 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']), - (1, executable+': failed CONTROL_FLOW')) - 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']), - (0, '')) - - clean_files(source, executable) - - def test_MACHO(self): - source = 'test1.cpp' - executable = 'test1' - cxx = determine_wellknown_cmd('CXX', 'clang++') - write_testcode(source) - arch = get_arch(cxx, source, executable) - - if arch == lief.ARCHITECTURES.X86: - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-fno-stack-protector', '-Wl,-no_fixup_chains']), - (1, executable+': failed NOUNDEFS Canary FIXUP_CHAINS PIE CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-flat_namespace','-fno-stack-protector', '-Wl,-fixup_chains']), - (1, executable+': failed NOUNDEFS Canary CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-flat_namespace','-fstack-protector-all', '-Wl,-fixup_chains']), - (1, executable+': failed NOUNDEFS CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-fstack-protector-all', '-Wl,-fixup_chains']), - (1, executable+': failed CONTROL_FLOW')) - self.assertEqual(call_security_check(cxx, source, executable, ['-fstack-protector-all', '-fcf-protection=full', '-Wl,-fixup_chains']), - (0, '')) - else: - # arm64 darwin doesn't support non-PIE binaries, control flow or executable stacks - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-flat_namespace','-fno-stack-protector', '-Wl,-no_fixup_chains']), - (1, executable+': failed NOUNDEFS Canary FIXUP_CHAINS BRANCH_PROTECTION')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-flat_namespace','-fno-stack-protector', '-Wl,-fixup_chains', '-mbranch-protection=bti']), - (1, executable+': failed NOUNDEFS Canary')) - self.assertEqual(call_security_check(cxx, source, executable, ['-Wl,-flat_namespace','-fstack-protector-all', '-Wl,-fixup_chains', '-mbranch-protection=bti']), - (1, executable+': failed NOUNDEFS')) - self.assertEqual(call_security_check(cxx, source, executable, ['-fstack-protector-all', '-Wl,-fixup_chains', '-mbranch-protection=bti']), - (0, '')) - - - clean_files(source, executable) - -if __name__ == '__main__': - unittest.main() diff --git a/contrib/devtools/test-symbol-check.py b/contrib/devtools/test-symbol-check.py deleted file mode 100755 index a562895a4e6e..000000000000 --- a/contrib/devtools/test-symbol-check.py +++ /dev/null @@ -1,175 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2020-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. -''' -Test script for symbol-check.py -''' -import os -import subprocess -from typing import List -import unittest - -from utils import determine_wellknown_cmd - -def call_symbol_check(cxx: List[str], source, executable, options): - # This should behave the same as AC_TRY_LINK, so arrange well-known flags - # in the same order as autoconf would. - # - # See the definitions for ac_link in autoconf's lib/autoconf/c.m4 file for - # reference. - env_flags: List[str] = [] - for var in ['CXXFLAGS', 'CPPFLAGS', 'LDFLAGS']: - env_flags += filter(None, os.environ.get(var, '').split(' ')) - - subprocess.run([*cxx,source,'-o',executable] + env_flags + options, check=True) - p = subprocess.run([os.path.join(os.path.dirname(__file__), 'symbol-check.py'), executable], stdout=subprocess.PIPE, text=True) - os.remove(source) - os.remove(executable) - return (p.returncode, p.stdout.rstrip()) - -class TestSymbolChecks(unittest.TestCase): - def test_ELF(self): - source = 'test1.cpp' - executable = 'test1' - cxx = determine_wellknown_cmd('CXX', 'g++') - - # -lutil is part of the libc6 package so a safe bet that it's installed - # it's also out of context enough that it's unlikely to ever become a real dependency - source = 'test2.cpp' - executable = 'test2' - with open(source, 'w', encoding="utf8") as f: - f.write(''' - #include - - int main() - { - login(0); - return 0; - } - ''') - - self.assertEqual(call_symbol_check(cxx, source, executable, ['-lutil']), - (1, executable + ': libutil.so.1 is not in ALLOWED_LIBRARIES!\n' + - executable + ': failed LIBRARY_DEPENDENCIES')) - - # finally, check a simple conforming binary - source = 'test3.cpp' - executable = 'test3' - with open(source, 'w', encoding="utf8") as f: - f.write(''' - #include - - int main() - { - std::printf("42"); - return 0; - } - ''') - - self.assertEqual(call_symbol_check(cxx, source, executable, []), - (0, '')) - - def test_MACHO(self): - source = 'test1.cpp' - executable = 'test1' - cxx = determine_wellknown_cmd('CXX', 'clang++') - - with open(source, 'w', encoding="utf8") as f: - f.write(''' - #include - - int main() - { - XML_ExpatVersion(); - return 0; - } - - ''') - - self.assertEqual(call_symbol_check(cxx, source, executable, ['-lexpat', '-Wl,-platform_version','-Wl,macos', '-Wl,11.4', '-Wl,11.4']), - (1, 'libexpat.1.dylib is not in ALLOWED_LIBRARIES!\n' + - f'{executable}: failed DYNAMIC_LIBRARIES MIN_OS SDK')) - - source = 'test2.cpp' - executable = 'test2' - with open(source, 'w', encoding="utf8") as f: - f.write(''' - #include - - int main() - { - CGMainDisplayID(); - return 0; - } - ''') - - self.assertEqual(call_symbol_check(cxx, source, executable, ['-framework', 'CoreGraphics', '-Wl,-platform_version','-Wl,macos', '-Wl,11.4', '-Wl,11.4']), - (1, f'{executable}: failed MIN_OS SDK')) - - source = 'test3.cpp' - executable = 'test3' - with open(source, 'w', encoding="utf8") as f: - f.write(''' - int main() - { - return 0; - } - ''') - - self.assertEqual(call_symbol_check(cxx, source, executable, ['-Wl,-platform_version','-Wl,macos', '-Wl,11.0', '-Wl,11.4']), - (1, f'{executable}: failed SDK')) - - def test_PE(self): - source = 'test1.cpp' - executable = 'test1.exe' - cxx = determine_wellknown_cmd('CXX', 'x86_64-w64-mingw32-g++') - - with open(source, 'w', encoding="utf8") as f: - f.write(''' - #include - - int main() - { - PdhConnectMachineA(NULL); - return 0; - } - ''') - - self.assertEqual(call_symbol_check(cxx, source, executable, ['-lpdh', '-Wl,--major-subsystem-version', '-Wl,6', '-Wl,--minor-subsystem-version', '-Wl,1']), - (1, 'pdh.dll is not in ALLOWED_LIBRARIES!\n' + - executable + ': failed DYNAMIC_LIBRARIES')) - - source = 'test2.cpp' - executable = 'test2.exe' - - with open(source, 'w', encoding="utf8") as f: - f.write(''' - int main() - { - return 0; - } - ''') - - self.assertEqual(call_symbol_check(cxx, source, executable, ['-Wl,--major-subsystem-version', '-Wl,9', '-Wl,--minor-subsystem-version', '-Wl,9']), - (1, executable + ': failed SUBSYSTEM_VERSION')) - - source = 'test3.cpp' - executable = 'test3.exe' - with open(source, 'w', encoding="utf8") as f: - f.write(''' - #include - - int main() - { - CoFreeUnusedLibrariesEx(0,0); - return 0; - } - ''') - - self.assertEqual(call_symbol_check(cxx, source, executable, ['-lole32', '-Wl,--major-subsystem-version', '-Wl,6', '-Wl,--minor-subsystem-version', '-Wl,1']), - (0, '')) - - -if __name__ == '__main__': - unittest.main() diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh index 4e378b000979..8c517368d17a 100755 --- a/contrib/guix/libexec/build.sh +++ b/contrib/guix/libexec/build.sh @@ -234,10 +234,15 @@ esac # LDFLAGS case "$HOST" in - *linux*) HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$glibc_dynamic_linker -static-libstdc++ -Wl,-O2" ;; + *linux*) HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$glibc_dynamic_linker -Wl,-O2" ;; *mingw*) HOST_LDFLAGS="-Wl,--no-insert-timestamp" ;; esac +# EXE FLAGS +case "$HOST" in + *linux*) HOST_LDFLAGS+=" -static-libstdc++ -static-libgcc" ;; +esac + mkdir -p "$DISTSRC" ( cd "$DISTSRC" @@ -272,8 +277,6 @@ mkdir -p "$DISTSRC" ;; esac - # 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} # Check that executables only contain allowed version symbols. diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm index 3a327e63e137..2f21f5b58801 100644 --- a/contrib/guix/manifest.scm +++ b/contrib/guix/manifest.scm @@ -93,16 +93,16 @@ chain for " target " development.")) (home-page (package-home-page xgcc)) (license (package-license xgcc))))) -(define base-gcc gcc-12) ;; 12.4.0 +(define base-gcc gcc-13) ;; 13.3.0 (define base-linux-kernel-headers linux-libre-headers-6.1) (define* (make-bitcoin-cross-toolchain target #:key - (base-gcc-for-libc linux-base-gcc) + (base-gcc-for-libc (gcc-libgcc-patches linux-base-gcc)) (base-kernel-headers base-linux-kernel-headers) (base-libc glibc-2.31) - (base-gcc linux-base-gcc)) + (base-gcc (gcc-libgcc-patches linux-base-gcc))) "Convenience wrapper around MAKE-CROSS-TOOLCHAIN with default values desirable for building Dash Core release binaries." (make-cross-toolchain target @@ -111,7 +111,7 @@ desirable for building Dash Core release binaries." base-libc base-gcc)) -(define (gcc-mingw-patches gcc) +(define (gcc-libgcc-patches gcc) (package-with-extra-patches gcc (search-our-patches "gcc-remap-guix-store.patch"))) @@ -128,10 +128,10 @@ desirable for building Dash Core release binaries." (let* ((xbinutils (binutils-mingw-patches (cross-binutils target))) (machine (substring target 0 (string-index target #\-))) (pthreads-xlibc (winpthreads-patches (make-mingw-w64 machine - #:xgcc (cross-gcc target #:xgcc (gcc-mingw-patches base-gcc)) + #:xgcc (cross-gcc target #:xgcc (gcc-libgcc-patches base-gcc)) #:with-winpthreads? #t))) (pthreads-xgcc (cross-gcc target - #:xgcc (gcc-mingw-patches mingw-w64-base-gcc) + #:xgcc (gcc-libgcc-patches mingw-w64-base-gcc) #:xbinutils xbinutils #:libc pthreads-xlibc))) ;; Define a meta-package that propagates the resulting XBINUTILS, XLIBC, and @@ -433,6 +433,7 @@ inspecting signatures in Mach-O binaries.") ;; https://gcc.gnu.org/install/configure.html (list "--enable-threads=posix", "--enable-default-ssp=yes", + "--disable-gcov", building-on))))))) (define-public linux-base-gcc @@ -448,6 +449,8 @@ inspecting signatures in Mach-O binaries.") "--enable-default-pie=yes", "--enable-standard-branch-protection=yes", "--enable-cet=yes", + "--disable-gcov", + "--disable-libsanitizer", building-on))) ((#:phases phases) `(modify-phases ,phases @@ -524,7 +527,7 @@ inspecting signatures in Mach-O binaries.") gzip xz ;; Build tools - gcc-toolchain-12 + gcc-toolchain-13 cmake-minimal gnu-make libtool @@ -546,7 +549,7 @@ inspecting signatures in Mach-O binaries.") osslsigncode)) ((string-contains target "-linux-") (list bison - (list gcc-toolchain-12 "static") + (list gcc-toolchain-13 "static") (make-bitcoin-cross-toolchain target))) ((string-contains target "darwin") (list clang-toolchain-19 diff --git a/contrib/guix/patches/gcc-remap-guix-store.patch b/contrib/guix/patches/gcc-remap-guix-store.patch index a8b41d485b04..4144bcd8cd1c 100644 --- a/contrib/guix/patches/gcc-remap-guix-store.patch +++ b/contrib/guix/patches/gcc-remap-guix-store.patch @@ -1,4 +1,4 @@ -Without ffile-prefix-map, the debug symbols will contain paths for the +Without -ffile-prefix-map, the debug symbols will contain paths for the guix store which will include the hashes of each package. However, the hash for the same package will differ when on different architectures. In order to be reproducible regardless of the architecture used to build @@ -6,7 +6,7 @@ the package, map all guix store prefixes to something fixed, e.g. /usr. --- a/libgcc/Makefile.in +++ b/libgcc/Makefile.in -@@ -854,7 +854,7 @@ endif +@@ -857,7 +857,7 @@ endif # libgcc_eh.a, only LIB2ADDEH matters. If we do, only LIB2ADDEHSTATIC and # LIB2ADDEHSHARED matter. (Usually all three are identical.) @@ -15,6 +15,15 @@ the package, map all guix store prefixes to something fixed, e.g. /usr. ifeq ($(enable_shared),yes) +@@ -880,7 +880,7 @@ endif + # Build LIBUNWIND. Use -fno-exceptions so that the unwind library does + # not generate calls to __gcc_personality_v0. + +-c_flags := -fno-exceptions ++c_flags := -fno-exceptions $(shell find /gnu/store -maxdepth 1 -mindepth 1 -type d -exec echo -n " -ffile-prefix-map={}=/usr" \;) + + libunwind-objects += $(addsuffix $(objext),$(basename $(notdir $(LIBUNWIND)))) + -- 2.37.0 diff --git a/contrib/devtools/security-check.py b/contrib/guix/security-check.py similarity index 78% rename from contrib/devtools/security-check.py rename to contrib/guix/security-check.py index db0e886525e8..0a5d1bbfa6f5 100755 --- a/contrib/devtools/security-check.py +++ b/contrib/guix/security-check.py @@ -6,7 +6,12 @@ Perform basic security checks on a series of executables. Exit status will be 0 if successful, and the program will be silent. Otherwise the exit status will be 1 and it will log which executables failed which checks. + +Example usage: + + find ../path/to/guix/binaries -type f -executable | xargs python3 contrib/guix/security-check.py ''' +import re import sys from typing import List @@ -39,13 +44,13 @@ def check_ELF_RELRO(binary) -> bool: return have_gnu_relro and have_bindnow -def check_ELF_Canary(binary) -> bool: +def check_ELF_CANARY(binary) -> bool: ''' Check for use of stack canary ''' return binary.has_symbol('__stack_chk_fail') -def check_ELF_separate_code(binary): +def check_ELF_SEPARATE_CODE(binary): ''' Check that sections are appropriately separated in virtual memory, based on their permissions. This checks for missing -Wl,-z,separate-code @@ -106,7 +111,7 @@ def check_ELF_separate_code(binary): return False return True -def check_ELF_control_flow(binary) -> bool: +def check_ELF_CONTROL_FLOW(binary) -> bool: ''' Check for control flow instrumentation ''' @@ -117,6 +122,24 @@ def check_ELF_control_flow(binary) -> bool: return True return False +def check_ELF_FORTIFY(binary) -> bool: + # dash-util does not currently contain any fortified functions + if 'Dash Core dash-util utility version ' in binary.strings: + return True + + chk_funcs = set() + + for sym in binary.imported_symbols: + match = re.search(r'__[a-z]*_chk', sym.name) + if match: + chk_funcs.add(match.group(0)) + + # ignore stack-protector and bdb + chk_funcs.discard('__stack_chk') + chk_funcs.discard('__db_chk') + + return len(chk_funcs) >= 1 + def check_PE_DYNAMIC_BASE(binary) -> bool: '''PIE: DllCharacteristics bit 0x40 signifies dynamicbase (ASLR)''' return lief.PE.DLL_CHARACTERISTICS.DYNAMIC_BASE in binary.optional_header.dll_characteristics_lists @@ -131,7 +154,7 @@ def check_PE_RELOC_SECTION(binary) -> bool: '''Check for a reloc section. This is required for functional ASLR.''' return binary.has_relocations -def check_PE_control_flow(binary) -> bool: +def check_PE_CONTROL_FLOW(binary) -> bool: ''' Check for control flow instrumentation ''' @@ -146,7 +169,7 @@ def check_PE_control_flow(binary) -> bool: return True return False -def check_PE_Canary(binary) -> bool: +def check_PE_CANARY(binary) -> bool: ''' Check for use of stack canary ''' @@ -164,7 +187,7 @@ def check_MACHO_FIXUP_CHAINS(binary) -> bool: ''' return binary.has_dyld_chained_fixups -def check_MACHO_Canary(binary) -> bool: +def check_MACHO_CANARY(binary) -> bool: ''' Check for use of stack canary ''' @@ -183,7 +206,7 @@ def check_NX(binary) -> bool: ''' return binary.has_nx -def check_MACHO_control_flow(binary) -> bool: +def check_MACHO_CONTROL_FLOW(binary) -> bool: ''' Check for control flow instrumentation ''' @@ -193,7 +216,7 @@ def check_MACHO_control_flow(binary) -> bool: return True return False -def check_MACHO_branch_protection(binary) -> bool: +def check_MACHO_BRANCH_PROTECTION(binary) -> bool: ''' Check for branch protection instrumentation ''' @@ -207,8 +230,8 @@ def check_MACHO_branch_protection(binary) -> bool: ('PIE', check_PIE), ('NX', check_NX), ('RELRO', check_ELF_RELRO), - ('Canary', check_ELF_Canary), - ('separate_code', check_ELF_separate_code), + ('CANARY', check_ELF_CANARY), + ('SEPARATE_CODE', check_ELF_SEPARATE_CODE), ] BASE_PE = [ @@ -217,23 +240,23 @@ def check_MACHO_branch_protection(binary) -> bool: ('HIGH_ENTROPY_VA', check_PE_HIGH_ENTROPY_VA), ('NX', check_NX), ('RELOC_SECTION', check_PE_RELOC_SECTION), - ('CONTROL_FLOW', check_PE_control_flow), - ('Canary', check_PE_Canary), + ('CONTROL_FLOW', check_PE_CONTROL_FLOW), + ('CANARY', check_PE_CANARY), ] BASE_MACHO = [ ('NOUNDEFS', check_MACHO_NOUNDEFS), - ('Canary', check_MACHO_Canary), + ('CANARY', check_MACHO_CANARY), ('FIXUP_CHAINS', check_MACHO_FIXUP_CHAINS), ] CHECKS = { lief.EXE_FORMATS.ELF: { - lief.ARCHITECTURES.X86: BASE_ELF + [('CONTROL_FLOW', check_ELF_control_flow)], - lief.ARCHITECTURES.ARM: BASE_ELF, - lief.ARCHITECTURES.ARM64: BASE_ELF, - lief.ARCHITECTURES.PPC: BASE_ELF, - lief.ARCHITECTURES.RISCV: BASE_ELF, + lief.ARCHITECTURES.X86: BASE_ELF + [('CONTROL_FLOW', check_ELF_CONTROL_FLOW), ('FORTIFY', check_ELF_FORTIFY)], + lief.ARCHITECTURES.ARM: BASE_ELF + [('FORTIFY', check_ELF_FORTIFY)], + lief.ARCHITECTURES.ARM64: BASE_ELF + [('FORTIFY', check_ELF_FORTIFY)], + lief.ARCHITECTURES.PPC: BASE_ELF + [('FORTIFY', check_ELF_FORTIFY)], + lief.ARCHITECTURES.RISCV: BASE_ELF, # Skip FORTIFY. See https://github.com/lief-project/LIEF/issues/1082. }, lief.EXE_FORMATS.PE: { lief.ARCHITECTURES.X86: BASE_PE, @@ -241,39 +264,24 @@ def check_MACHO_branch_protection(binary) -> bool: lief.EXE_FORMATS.MACHO: { lief.ARCHITECTURES.X86: BASE_MACHO + [('PIE', check_PIE), ('NX', check_NX), - ('CONTROL_FLOW', check_MACHO_control_flow)], - lief.ARCHITECTURES.ARM64: BASE_MACHO + [('BRANCH_PROTECTION', check_MACHO_branch_protection)], + ('CONTROL_FLOW', check_MACHO_CONTROL_FLOW)], + lief.ARCHITECTURES.ARM64: BASE_MACHO + [('BRANCH_PROTECTION', check_MACHO_BRANCH_PROTECTION)], } } if __name__ == '__main__': retval: int = 0 for filename in sys.argv[1:]: - try: - binary = lief.parse(filename) - etype = binary.format - arch = binary.abstract.header.architecture - binary.concrete - - if etype == lief.EXE_FORMATS.UNKNOWN: - print(f'{filename}: unknown executable format') - retval = 1 - continue - - if arch == lief.ARCHITECTURES.NONE: - print(f'{filename}: unknown architecture') - retval = 1 - continue - - failed: List[str] = [] - for (name, func) in CHECKS[etype][arch]: - if not func(binary): - failed.append(name) - if failed: - print(f'{filename}: failed {" ".join(failed)}') - retval = 1 - except IOError: - print(f'{filename}: cannot open') + binary = lief.parse(filename) + etype = binary.format + arch = binary.abstract.header.architecture + binary.concrete + + failed: List[str] = [] + for (name, func) in CHECKS[etype][arch]: + if not func(binary): + failed.append(name) + if failed: + print(f'{filename}: failed {" ".join(failed)}') retval = 1 sys.exit(retval) - diff --git a/contrib/devtools/symbol-check.py b/contrib/guix/symbol-check.py similarity index 88% rename from contrib/devtools/symbol-check.py rename to contrib/guix/symbol-check.py index c296ad16fb9a..bca9029b24d8 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/guix/symbol-check.py @@ -8,7 +8,7 @@ Example usage: - find ../path/to/binaries -type f -executable | xargs python3 contrib/devtools/symbol-check.py + find ../path/to/guix/binaries -type f -executable | xargs python3 contrib/guix/symbol-check.py ''' import sys from typing import Dict, List @@ -17,23 +17,18 @@ # Debian 11 (Bullseye) EOL: 2026. https://wiki.debian.org/LTS # -# - libgcc version 10.2.1 (https://packages.debian.org/bullseye/libgcc-s1) # - libc version 2.31 (https://packages.debian.org/source/bullseye/glibc) # # Ubuntu 20.04 (Focal) EOL: 2030. https://wiki.ubuntu.com/ReleaseTeam # -# - libgcc version 10.5.0 (https://packages.ubuntu.com/focal/libgcc1) # - libc version 2.31 (https://packages.ubuntu.com/focal/libc6) # # CentOS Stream 9 EOL: 2027. https://www.centos.org/cl-vs-cs/#end-of-life # -# - libgcc version 12.2.1 (https://mirror.stream.centos.org/9-stream/AppStream/x86_64/os/Packages/) # - libc version 2.34 (https://mirror.stream.centos.org/9-stream/AppStream/x86_64/os/Packages/) # -# See https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html for more info. MAX_VERSIONS = { -'GCC': (4,3,0), 'GLIBC': { lief.ELF.ARCH.x86_64: (2,31), lief.ELF.ARCH.ARM: (2,31), @@ -41,7 +36,6 @@ lief.ELF.ARCH.PPC64: (2,31), lief.ELF.ARCH.RISCV: (2,31), }, -'LIBATOMIC': (1,0), 'V': (0,5,0), # xkb (bitcoin-qt only) } @@ -97,11 +91,9 @@ # Allowed NEEDED libraries ELF_ALLOWED_LIBRARIES = { # dashd and dash-qt -'libgcc_s.so.1', # GCC base support 'libc.so.6', # C library 'libpthread.so.0', # threading 'libm.so.6', # math library -'libatomic.so.1', 'ld-linux-x86-64.so.2', # 64-bit dynamic linker 'ld-linux.so.2', # 32-bit dynamic linker 'ld-linux-aarch64.so.1', # 64-bit ARM dynamic linker @@ -157,13 +149,13 @@ } PE_ALLOWED_LIBRARIES = { -'ADVAPI32.dll', # security & registry +'ADVAPI32.dll', # legacy security & registry +'bcrypt.dll', # newer security and identity API 'IPHLPAPI.DLL', # IP helper API 'KERNEL32.dll', # win32 base APIs 'msvcrt.dll', # C standard library for MSVC 'SHELL32.dll', # shell API 'WS2_32.dll', # sockets -'bcrypt.dll', # crypto API 'dbghelp.dll', # debugging routines # bitcoin-qt only 'dwmapi.dll', # desktop window manager @@ -243,7 +235,7 @@ def check_MACHO_libraries(binary) -> bool: return ok def check_MACHO_min_os(binary) -> bool: - if binary.build_version.minos == [11,0,0]: + if binary.build_version.minos == [14,0,0]: return True return False @@ -268,7 +260,7 @@ def check_PE_libraries(binary) -> bool: def check_PE_subsystem_version(binary) -> bool: major: int = binary.optional_header.major_subsystem_version minor: int = binary.optional_header.minor_subsystem_version - if major == 6 and minor == 1: + if major == 6 and minor == 2: return True return False @@ -308,22 +300,14 @@ def check_ELF_ABI(binary) -> bool: if __name__ == '__main__': retval: int = 0 for filename in sys.argv[1:]: - try: - binary = lief.parse(filename) - etype = binary.format - if etype == lief.EXE_FORMATS.UNKNOWN: - print(f'{filename}: unknown executable format') - retval = 1 - continue - - failed: List[str] = [] - for (name, func) in CHECKS[etype]: - if not func(binary): - failed.append(name) - if failed: - print(f'{filename}: failed {" ".join(failed)}') - retval = 1 - except IOError: - print(f'{filename}: cannot open') + binary = lief.parse(filename) + etype = binary.format + + failed: List[str] = [] + for (name, func) in CHECKS[etype]: + if not func(binary): + failed.append(name) + if failed: + print(f'{filename}: failed {" ".join(failed)}') retval = 1 sys.exit(retval) diff --git a/depends/funcs.mk b/depends/funcs.mk index 964be8ea61c5..ec514600b7fb 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -190,7 +190,7 @@ ifeq ($($(1)_type),build) $(1)_cmake += -DCMAKE_INSTALL_RPATH:PATH="$$($($(1)_type)_prefix)/lib" else ifneq ($(host),$(build)) -$(1)_cmake += -DCMAKE_SYSTEM_NAME=$($(host_os)_cmake_system) +$(1)_cmake += -DCMAKE_SYSTEM_NAME=$($(host_os)_cmake_system_name) $(1)_cmake += -DCMAKE_C_COMPILER_TARGET=$(host) $(1)_cmake += -DCMAKE_CXX_COMPILER_TARGET=$(host) endif diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index 845ff03d6bae..1b187711bfd8 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -1,4 +1,4 @@ -OSX_MIN_VERSION=11.0 +OSX_MIN_VERSION=14.0 OSX_SDK_VERSION=14.0 XCODE_VERSION=15.0 XCODE_BUILD_ID=15A240d @@ -76,4 +76,7 @@ darwin_release_CXXFLAGS=$(darwin_release_CFLAGS) darwin_debug_CFLAGS=-O1 -g darwin_debug_CXXFLAGS=$(darwin_debug_CFLAGS) -darwin_cmake_system=Darwin +darwin_cmake_system_name=Darwin +# Darwin version, which corresponds to OSX_MIN_VERSION. +# See https://en.wikipedia.org/wiki/Darwin_(operating_system) +darwin_cmake_system_version=23.0 diff --git a/depends/hosts/freebsd.mk b/depends/hosts/freebsd.mk index 3b265f647dc7..009d215f82f8 100644 --- a/depends/hosts/freebsd.mk +++ b/depends/hosts/freebsd.mk @@ -28,4 +28,4 @@ x86_64_freebsd_CC=$(default_host_CC) -m64 x86_64_freebsd_CXX=$(default_host_CXX) -m64 endif -freebsd_cmake_system=FreeBSD +freebsd_cmake_system_name=FreeBSD diff --git a/depends/hosts/linux.mk b/depends/hosts/linux.mk index f5ce2bb0b855..e2f34265d153 100644 --- a/depends/hosts/linux.mk +++ b/depends/hosts/linux.mk @@ -39,4 +39,7 @@ i686_linux_CXX=$(default_host_CXX) -m32 x86_64_linux_CC=$(default_host_CC) -m64 x86_64_linux_CXX=$(default_host_CXX) -m64 endif -linux_cmake_system=Linux + +linux_cmake_system_name=Linux +# Refer to doc/dependencies.md for the minimum required kernel. +linux_cmake_system_version=3.17.0 diff --git a/depends/hosts/mingw32.mk b/depends/hosts/mingw32.mk index e324fd2fffe6..48db7fe863dd 100644 --- a/depends/hosts/mingw32.mk +++ b/depends/hosts/mingw32.mk @@ -21,4 +21,6 @@ mingw32_debug_CXXFLAGS=$(mingw32_debug_CFLAGS) mingw32_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -mingw32_cmake_system=Windows +mingw32_cmake_system_name=Windows +# Windows 10 +mingw32_cmake_system_version=10.0 diff --git a/depends/hosts/netbsd.mk b/depends/hosts/netbsd.mk index 842c015ca30a..d2b79f9d5bf3 100644 --- a/depends/hosts/netbsd.mk +++ b/depends/hosts/netbsd.mk @@ -34,4 +34,4 @@ x86_64_netbsd_CC=$(default_host_CC) -m64 x86_64_netbsd_CXX=$(default_host_CXX) -m64 endif -netbsd_cmake_system=NetBSD +netbsd_cmake_system_name=NetBSD diff --git a/depends/hosts/openbsd.mk b/depends/hosts/openbsd.mk index b6db8575ff7a..53595689b62e 100644 --- a/depends/hosts/openbsd.mk +++ b/depends/hosts/openbsd.mk @@ -28,4 +28,4 @@ x86_64_openbsd_CC=$(default_host_CC) -m64 x86_64_openbsd_CXX=$(default_host_CXX) -m64 endif -openbsd_cmake_system=OpenBSD +openbsd_cmake_system_name=OpenBSD diff --git a/depends/packages.md b/depends/packages.md index 0ffdc66d4884..4232bb1006bd 100644 --- a/depends/packages.md +++ b/depends/packages.md @@ -6,7 +6,7 @@ The package "mylib" will be used here as an example General tips: - mylib_foo is written as $(package)_foo in order to make recipes more similar. - Secondary dependency packages relative to the bitcoin binaries/libraries (i.e. - those not in `ALLOWED_LIBRARIES` in `contrib/devtools/symbol-check.py`) don't + those not in `ALLOWED_LIBRARIES` in `contrib/guix/symbol-check.py`) don't need to be shared and should be built statically whenever possible. See [below](#secondary-dependencies) for more details. @@ -168,7 +168,7 @@ the Autotools `--with-pic` flag, or `CMAKE_POSITION_INDEPENDENT_CODE` with CMake ## Secondary dependencies: Secondary dependency packages relative to the bitcoin binaries/libraries (i.e. -those not in `ALLOWED_LIBRARIES` in `contrib/devtools/symbol-check.py`) don't +those not in `ALLOWED_LIBRARIES` in `contrib/guix/symbol-check.py`) don't need to be shared and should be built statically whenever possible. This improves general build reliability as illustrated by the following example: diff --git a/depends/packages/capnp.mk b/depends/packages/capnp.mk index 0964ede3d31b..7f41d3b5a4ed 100644 --- a/depends/packages/capnp.mk +++ b/depends/packages/capnp.mk @@ -4,8 +4,6 @@ $(package)_download_path=$(native_$(package)_download_path) $(package)_download_file=$(native_$(package)_download_file) $(package)_file_name=$(native_$(package)_file_name) $(package)_sha256_hash=$(native_$(package)_sha256_hash) -$(package)_patches=abi_placement_new.patch -$(package)_patches += fix_openbsd_build.patch define $(package)_set_vars := $(package)_config_opts := -DBUILD_TESTING=OFF @@ -14,11 +12,6 @@ define $(package)_set_vars := $(package)_cxxflags += -fdebug-prefix-map=$($(package)_extract_dir)=/usr -fmacro-prefix-map=$($(package)_extract_dir)=/usr endef -define $(package)_preprocess_cmds - patch -p2 < $($(package)_patch_dir)/abi_placement_new.patch && \ - patch -p2 < $($(package)_patch_dir)/fix_openbsd_build.patch -endef - define $(package)_config_cmds $($(package)_cmake) . endef diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk index bcc7cd067030..4997121f4fc8 100644 --- a/depends/packages/libevent.mk +++ b/depends/packages/libevent.mk @@ -10,7 +10,7 @@ $(package)_patches += winver_fixup.patch $(package)_build_subdir=build # When building for Windows, we set _WIN32_WINNT to target the same Windows -# version as we do in configure. Due to quirks in libevents build system, this +# version as we do in releases. Due to quirks in libevents build system, this # is also required to enable support for ipv6. See #19375. define $(package)_set_vars $(package)_config_opts=-DCMAKE_BUILD_TYPE=None -DEVENT__DISABLE_BENCHMARK=ON -DEVENT__DISABLE_OPENSSL=ON @@ -18,7 +18,7 @@ define $(package)_set_vars $(package)_config_opts+=-DEVENT__DISABLE_TESTS=ON -DEVENT__LIBRARY_TYPE=STATIC $(package)_cflags += -fdebug-prefix-map=$($(package)_extract_dir)=/usr -fmacro-prefix-map=$($(package)_extract_dir)=/usr $(package)_cppflags += -D_GNU_SOURCE - $(package)_cppflags_mingw32=-D_WIN32_WINNT=0x0601 + $(package)_cppflags_mingw32=-D_WIN32_WINNT=0x0A00 ifeq ($(NO_HARDEN),) $(package)_cppflags += -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk index da32797ea60f..b3b3e999d3f0 100644 --- a/depends/packages/miniupnpc.mk +++ b/depends/packages/miniupnpc.mk @@ -9,7 +9,7 @@ $(package)_patches=dont_leak_info.patch respect_mingw_cflags.patch no_libtool.pa # See discussion in https://github.com/bitcoin/bitcoin/pull/25964. define $(package)_set_vars $(package)_build_opts=CC="$($(package)_cc)" -$(package)_build_opts_mingw32=-f Makefile.mingw CFLAGS="$($(package)_cflags) -D_WIN32_WINNT=0x0601" +$(package)_build_opts_mingw32=-f Makefile.mingw CFLAGS="$($(package)_cflags) -D_WIN32_WINNT=0x0A00" $(package)_build_env+=CFLAGS="$($(package)_cflags) $($(package)_cppflags)" AR="$($(package)_ar)" endef diff --git a/depends/packages/native_capnp.mk b/depends/packages/native_capnp.mk index c886d8e239df..0cd0dcdf9d92 100644 --- a/depends/packages/native_capnp.mk +++ b/depends/packages/native_capnp.mk @@ -1,10 +1,9 @@ package=native_capnp -$(package)_version=1.1.0 +$(package)_version=1.3.0 $(package)_download_path=https://capnproto.org/ $(package)_download_file=capnproto-c++-$($(package)_version).tar.gz $(package)_file_name=capnproto-cxx-$($(package)_version).tar.gz -$(package)_sha256_hash=07167580e563f5e821e3b2af1c238c16ec7181612650c5901330fa9a0da50939 -$(package)_patches=fix_openbsd_build.patch +$(package)_sha256_hash=098f824a495a1a837d56ae17e07b3f721ac86f8dbaf58896a389923458522108 define $(package)_set_vars $(package)_config_opts := -DBUILD_TESTING=OFF @@ -12,10 +11,6 @@ define $(package)_set_vars $(package)_config_opts += -DWITH_ZLIB=OFF endef -define $(package)_preprocess_cmds - patch -p2 < $($(package)_patch_dir)/fix_openbsd_build.patch -endef - define $(package)_config_cmds $($(package)_cmake) . endef diff --git a/depends/packages/native_libmultiprocess.mk b/depends/packages/native_libmultiprocess.mk index 8273f1508466..412d7d0a54cc 100644 --- a/depends/packages/native_libmultiprocess.mk +++ b/depends/packages/native_libmultiprocess.mk @@ -1,8 +1,8 @@ package=native_libmultiprocess -$(package)_version=6aca5f389bacf2942394b8738bbe15d6c9edfb9b +$(package)_version=abe254b9734f2e2b220d1456de195532d6e6ac1e $(package)_download_path=https://github.com/bitcoin-core/libmultiprocess/archive $(package)_file_name=$($(package)_version).tar.gz -$(package)_sha256_hash=2efeed53542bc1d8af3291f2b6f0e5d430d86a5e04e415ce33c136f2c226a51d +$(package)_sha256_hash=85777073259fdc75d24ac5777a19991ec1156c5f12db50b252b861c95dcb4f46 $(package)_dependencies=native_capnp define $(package)_config_cmds diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 9cb0831d22cb..45da9259247e 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -20,7 +20,7 @@ define $(package)_set_vars $(package)_config_opts += -DBUILD_SHARED=OFF -DBUILD_TESTS=OFF -DZMQ_BUILD_TESTS=OFF $(package)_config_opts += -DENABLE_DRAFTS=OFF -DZMQ_BUILD_TESTS=OFF $(package)_cxxflags += -fdebug-prefix-map=$($(package)_extract_dir)=/usr -fmacro-prefix-map=$($(package)_extract_dir)=/usr - $(package)_config_opts_mingw32 += -DZMQ_WIN32_WINNT=0x0601 -DZMQ_HAVE_IPC=OFF + $(package)_config_opts_mingw32 += -DZMQ_WIN32_WINNT=0x0A00 -DZMQ_HAVE_IPC=OFF endef define $(package)_preprocess_cmds diff --git a/depends/patches/capnp/abi_placement_new.patch b/depends/patches/capnp/abi_placement_new.patch deleted file mode 100644 index 9aef85db8e86..000000000000 --- a/depends/patches/capnp/abi_placement_new.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 74560f26f75dda4257dce541ca362a1e763b2971 Mon Sep 17 00:00:00 2001 -From: Ryan Ofsky -Date: Thu, 6 Feb 2025 08:39:05 -0500 -Subject: [PATCH 1/1] Avoid gcc/clang ABI incompatibility caused by - PlacementNew - -GCC and clang do not use same calling convention for passing empty struct -parameters. There is more information about this in -https://itanium-cxx-abi.github.io/cxx-abi/cxx-abi-dev/archives/2015-December/002869.html - -Unfortunately this can create an issue in capnproto if it is built without -optimizations in GCC, and the resulting static libraries are used in a clang -program, or vice versa. - -Depending on what order libraries are specified on the linker command line, and -whether code compiled with the other compiler is calling any header functions -that cause weak a `operator new(unsigned int, kj::_::PlacementNew, void*)` -symbol to be defined in its own objects, this can cause the linker to link a -GCC-generated `kj::ctor` with a clang-generated `operator new`, and the -resulting program to crash due to the compilers using different calling -conventions for `operator new`. - -This problem is difficult to avoid in general, but pretty easy to avoid here by -changing `operator new` parameter order so the empty struct parameter is last. - -This change should be beneficial for capnproto users that may be compiling it -without optimizations, and not necessarily using a single compiler to build all -their dependencies. - -The problem does not occur if any optimizations are enabled because `operator -new` calls are inlined in that case. ---- - c++/src/kj/common.h | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - -diff --git a/c++/src/kj/common.h b/c++/src/kj/common.h -index b8edde3c..28ab11d6 100644 ---- a/c++/src/kj/common.h -+++ b/c++/src/kj/common.h -@@ -1034,24 +1034,27 @@ private: - - // We want placement new, but we don't want to #include . operator new cannot be defined in - // a namespace, and defining it globally conflicts with the definition in . So we have to --// define a dummy type and an operator new that uses it. -+// define a dummy type and an operator new that uses it. The dummy type is intentionally passed -+// as the last parameter so clang and GCC ABI calling conventions for empty struct struct parameters -+// are compatible, and there are not segfaults trying to call clang operator new/delete from GCC or -+// vice versa. - - namespace _ { // private - struct PlacementNew {}; - } // namespace _ (private) - } // namespace kj - --inline void* operator new(size_t, kj::_::PlacementNew, void* __p) noexcept { -+inline void* operator new(size_t, void* __p, kj::_::PlacementNew) noexcept { - return __p; - } - --inline void operator delete(void*, kj::_::PlacementNew, void* __p) noexcept {} -+inline void operator delete(void*, void* __p, kj::_::PlacementNew) noexcept {} - - namespace kj { - - template - inline void ctor(T& location, Params&&... params) { -- new (_::PlacementNew(), &location) T(kj::fwd(params)...); -+ new (&location, _::PlacementNew()) T(kj::fwd(params)...); - } - - template diff --git a/depends/patches/capnp/fix_openbsd_build.patch b/depends/patches/capnp/fix_openbsd_build.patch deleted file mode 100644 index eb143c61e4dc..000000000000 --- a/depends/patches/capnp/fix_openbsd_build.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0cd1792332dce6a3afae6e2bc2939da69fea65fa Mon Sep 17 00:00:00 2001 -From: Sebastian Falbesoner -Date: Sat, 31 May 2025 00:49:44 +0200 -Subject: [PATCH 1/2] In cidr.c++, include on all non-Windows - systems - -The motivation for this commit is to fix the build for OpenBSD, -but it may also solves the same potential problem for other systems -without causing any harm. - -Suggested already twice, see -https://github.com/capnproto/capnproto/pull/1846#discussion_r1399499535 -https://github.com/capnproto/capnproto/pull/1907#discussion_r1452602424 ---- - c++/src/kj/cidr.c++ | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/c++/src/kj/cidr.c++ b/c++/src/kj/cidr.c++ -index 6a1fa32e..9432b8f4 100644 ---- a/c++/src/kj/cidr.c++ -+++ b/c++/src/kj/cidr.c++ -@@ -39,9 +39,6 @@ - #else - #include - #include --#endif -- --#if __FreeBSD__ - #include - #endif - --- -2.49.0 - - -From 2e76d17db3fc484061487c0779b16495939d30c3 Mon Sep 17 00:00:00 2001 -From: Sebastian Falbesoner -Date: Sat, 31 May 2025 01:06:42 +0200 -Subject: [PATCH 2/2] Don't set KJ_USE_KQUEUE on OpenBSD - -OpenBSD doesn't support user event filters yet, hence -the build fails as it misses the symbol EVFILT_USER in -the kqueue implementation in async-unix.c++. Fix that -by not setting KJ_USE_KQUEUE on OpenBSD, so the poll()- -based implementation is used instead. - -Suggested in -https://github.com/capnproto/capnproto/pull/1907/commits/829d3f03735f8f6762a50fc346db56bf02140f02#r1452600300 ---- - c++/src/kj/async-unix.h | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/c++/src/kj/async-unix.h b/c++/src/kj/async-unix.h -index 665305ea..e66ad8e4 100644 ---- a/c++/src/kj/async-unix.h -+++ b/c++/src/kj/async-unix.h -@@ -37,8 +37,9 @@ KJ_BEGIN_HEADER - #if __linux__ - // Default to epoll on Linux. - #define KJ_USE_EPOLL 1 --#elif __APPLE__ || __FreeBSD__ || __OpenBSD__ || __NetBSD__ || __DragonFly__ --// MacOS and BSDs prefer kqueue() for event notification. -+#elif __APPLE__ || __FreeBSD__ || __NetBSD__ || __DragonFly__ -+// MacOS and most BSDs prefer kqueue() for event notification. -+// (Note that OpenBSD's kqueue(2) doesn't support user event filters yet) - #define KJ_USE_KQUEUE 1 - #endif - #endif --- -2.49.0 - diff --git a/depends/patches/native_capnp/fix_openbsd_build.patch b/depends/patches/native_capnp/fix_openbsd_build.patch deleted file mode 100644 index eb143c61e4dc..000000000000 --- a/depends/patches/native_capnp/fix_openbsd_build.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0cd1792332dce6a3afae6e2bc2939da69fea65fa Mon Sep 17 00:00:00 2001 -From: Sebastian Falbesoner -Date: Sat, 31 May 2025 00:49:44 +0200 -Subject: [PATCH 1/2] In cidr.c++, include on all non-Windows - systems - -The motivation for this commit is to fix the build for OpenBSD, -but it may also solves the same potential problem for other systems -without causing any harm. - -Suggested already twice, see -https://github.com/capnproto/capnproto/pull/1846#discussion_r1399499535 -https://github.com/capnproto/capnproto/pull/1907#discussion_r1452602424 ---- - c++/src/kj/cidr.c++ | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/c++/src/kj/cidr.c++ b/c++/src/kj/cidr.c++ -index 6a1fa32e..9432b8f4 100644 ---- a/c++/src/kj/cidr.c++ -+++ b/c++/src/kj/cidr.c++ -@@ -39,9 +39,6 @@ - #else - #include - #include --#endif -- --#if __FreeBSD__ - #include - #endif - --- -2.49.0 - - -From 2e76d17db3fc484061487c0779b16495939d30c3 Mon Sep 17 00:00:00 2001 -From: Sebastian Falbesoner -Date: Sat, 31 May 2025 01:06:42 +0200 -Subject: [PATCH 2/2] Don't set KJ_USE_KQUEUE on OpenBSD - -OpenBSD doesn't support user event filters yet, hence -the build fails as it misses the symbol EVFILT_USER in -the kqueue implementation in async-unix.c++. Fix that -by not setting KJ_USE_KQUEUE on OpenBSD, so the poll()- -based implementation is used instead. - -Suggested in -https://github.com/capnproto/capnproto/pull/1907/commits/829d3f03735f8f6762a50fc346db56bf02140f02#r1452600300 ---- - c++/src/kj/async-unix.h | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/c++/src/kj/async-unix.h b/c++/src/kj/async-unix.h -index 665305ea..e66ad8e4 100644 ---- a/c++/src/kj/async-unix.h -+++ b/c++/src/kj/async-unix.h -@@ -37,8 +37,9 @@ KJ_BEGIN_HEADER - #if __linux__ - // Default to epoll on Linux. - #define KJ_USE_EPOLL 1 --#elif __APPLE__ || __FreeBSD__ || __OpenBSD__ || __NetBSD__ || __DragonFly__ --// MacOS and BSDs prefer kqueue() for event notification. -+#elif __APPLE__ || __FreeBSD__ || __NetBSD__ || __DragonFly__ -+// MacOS and most BSDs prefer kqueue() for event notification. -+// (Note that OpenBSD's kqueue(2) doesn't support user event filters yet) - #define KJ_USE_KQUEUE 1 - #endif - #endif --- -2.49.0 - diff --git a/doc/build-osx.md b/doc/build-osx.md index e6e9384356c3..87914d09affc 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -1,15 +1,15 @@ # macOS Build Guide -**Updated for MacOS [11.2](https://www.apple.com/macos/big-sur/)** +**Updated for macOS [14](https://developer.apple.com/documentation/macos-release-notes/macos-14-release-notes/)** -This guide describes how to build dashd, command-line utilities, and GUI on macOS +This guide describes how to build dashd, command-line utilities, and GUI on macOS. ## Preparation The commands in this guide should be executed in a Terminal application. macOS comes with a built-in Terminal located in: -``` +```bash /Applications/Utilities/Terminal.app ``` @@ -50,20 +50,6 @@ See [dependencies.md](dependencies.md) for a complete overview. brew install automake libtool boost gmp pkg-config libevent ``` -For macOS 11 (Big Sur) and 12 (Monterey) you need to install a more recent version of llvm. - -``` bash -brew install llvm -``` - -And append the following to the configure commands below: - -``` bash -CC=$(brew --prefix llvm)/bin/clang CXX=$(brew --prefix llvm)/bin/clang++ -``` - -Try `llvm@17` if compilation fails with the default version of llvm. - ### 4. Clone Dash repository `git` should already be installed by default on your system. diff --git a/doc/release-notes-6927.md b/doc/release-notes-6927.md new file mode 100644 index 000000000000..faa8cd20bf15 --- /dev/null +++ b/doc/release-notes-6927.md @@ -0,0 +1,4 @@ +Build System +------------ + +Dash Core binaries will now target Windows 10 and macOS 14 (Sonoma), replacing the previous target Windows 7 and macOS 11 (Big Sur). diff --git a/doc/release-notes-empty-template.md b/doc/release-notes-empty-template.md index b129c6c599fc..f6b52ae6c7a6 100644 --- a/doc/release-notes-empty-template.md +++ b/doc/release-notes-empty-template.md @@ -29,6 +29,14 @@ installer (on Windows) or just copy over `/Applications/Dash-Qt` (on macOS) or Downgrading to a version older than *version* may not be supported, and will likely require a reindex. +# Compatibility + +Dash Core is supported and tested on operating systems using the +Linux Kernel 3.17+, macOS 14+, and Windows 10+. Dash Core +should also work on most other Unix-like systems but is not as +frequently tested on them. It is not recommended to use Dash Core on +unsupported systems. + # Release Notes Notable changes diff --git a/share/qt/Info.plist.in b/share/qt/Info.plist.in index 81638b679803..2c0c7ba4a91e 100644 --- a/share/qt/Info.plist.in +++ b/share/qt/Info.plist.in @@ -3,7 +3,7 @@ LSMinimumSystemVersion - 11 + 14 LSArchitecturePriority diff --git a/src/Makefile.am b/src/Makefile.am index 47f3c6bd55fc..073e1461db77 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1233,12 +1233,12 @@ clean-local: check-symbols: $(bin_PROGRAMS) @echo "Running symbol and dynamic library checks..." - $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS) + $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/guix/symbol-check.py $(bin_PROGRAMS) check-security: $(bin_PROGRAMS) if HARDEN @echo "Checking binary security..." - $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/security-check.py $(bin_PROGRAMS) + $(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/guix/security-check.py $(bin_PROGRAMS) endif diff --git a/src/ipc/.clang-tidy b/src/ipc/.clang-tidy new file mode 100644 index 000000000000..68dcb297959f --- /dev/null +++ b/src/ipc/.clang-tidy @@ -0,0 +1,5 @@ +Checks: + # See: https://github.com/capnproto/capnproto/pull/2334. + - "-clang-analyzer-core.UndefinedBinaryOperatorResult" + # See: https://github.com/capnproto/capnproto/pull/2417. + - "-clang-analyzer-security.ArrayBound" diff --git a/src/random.cpp b/src/random.cpp index 8f565000d9d6..3b5266ffc6ea 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -23,8 +23,7 @@ #include #ifdef WIN32 -#include -#include +#include #else #include #endif @@ -349,16 +348,15 @@ static void GetDevURandom(unsigned char *ent32) void GetOSRand(unsigned char *ent32) { #if defined(WIN32) - HCRYPTPROV hProvider; - int ret = CryptAcquireContextW(&hProvider, nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); - if (!ret) { - RandFailure(); - } - ret = CryptGenRandom(hProvider, NUM_OS_RANDOM_BYTES, ent32); - if (!ret) { + constexpr uint32_t STATUS_SUCCESS{0x00000000}; + NTSTATUS status = BCryptGenRandom(/*hAlgorithm=*/NULL, + /*pbBuffer=*/ent32, + /*cbBuffer=*/NUM_OS_RANDOM_BYTES, + /*dwFlags=*/BCRYPT_USE_SYSTEM_PREFERRED_RNG); + + if (status != STATUS_SUCCESS) { RandFailure(); } - CryptReleaseContext(hProvider, 0); #elif defined(HAVE_SYS_GETRANDOM) /* Linux. From the getrandom(2) man page: * "If the urandom source has been initialized, reads of up to 256 bytes diff --git a/src/test/.clang-tidy b/src/test/.clang-tidy new file mode 100644 index 000000000000..92d24f6f660a --- /dev/null +++ b/src/test/.clang-tidy @@ -0,0 +1,3 @@ +Checks: + # See: https://github.com/capnproto/capnproto/pull/2417. + - "-clang-analyzer-security.ArrayBound" diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 15854fb3f7b5..44047a7fe576 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -40,23 +40,23 @@ CROSS = "x " CIRCLE = "o " -if os.name != 'nt' or sys.getwindowsversion() >= (10, 0, 14393): #type:ignore - if os.name == 'nt': - import ctypes - kernel32 = ctypes.windll.kernel32 # type: ignore - ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4 - STD_OUTPUT_HANDLE = -11 - STD_ERROR_HANDLE = -12 - # Enable ascii color control to stdout - stdout = kernel32.GetStdHandle(STD_OUTPUT_HANDLE) - stdout_mode = ctypes.c_int32() - kernel32.GetConsoleMode(stdout, ctypes.byref(stdout_mode)) - kernel32.SetConsoleMode(stdout, stdout_mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING) - # Enable ascii color control to stderr - stderr = kernel32.GetStdHandle(STD_ERROR_HANDLE) - stderr_mode = ctypes.c_int32() - kernel32.GetConsoleMode(stderr, ctypes.byref(stderr_mode)) - kernel32.SetConsoleMode(stderr, stderr_mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING) +if os.name == 'nt': #type:ignore + import ctypes + kernel32 = ctypes.windll.kernel32 # type: ignore + ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4 + STD_OUTPUT_HANDLE = -11 + STD_ERROR_HANDLE = -12 + # Enable ascii color control to stdout + stdout = kernel32.GetStdHandle(STD_OUTPUT_HANDLE) + stdout_mode = ctypes.c_int32() + kernel32.GetConsoleMode(stdout, ctypes.byref(stdout_mode)) + kernel32.SetConsoleMode(stdout, stdout_mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING) + # Enable ascii color control to stderr + stderr = kernel32.GetStdHandle(STD_ERROR_HANDLE) + stderr_mode = ctypes.c_int32() + kernel32.GetConsoleMode(stderr, ctypes.byref(stderr_mode)) + kernel32.SetConsoleMode(stderr, stderr_mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING) +else: # primitive formatting on supported # terminal via ANSI escape sequences: DEFAULT = ('\033[0m', '\033[0m') diff --git a/test/get_previous_releases.py b/test/get_previous_releases.py index e900c5baeb29..a1f60346f03a 100755 --- a/test/get_previous_releases.py +++ b/test/get_previous_releases.py @@ -188,8 +188,8 @@ def download_binary(tag, args) -> int: Path(tarball).unlink() - if tag >= "v19" and platform == "arm64-apple-darwin": - # Starting with v23 there are arm64 binaries for ARM (e.g. M1, M2) macs, but they have to be signed to run + if tag >= "v19" and args.host == "arm64-apple-darwin": + # Starting with v19 there are arm64 binaries for ARM (e.g. M1, M2) macs, but they have to be signed to run binary_path = f'{os.getcwd()}/{tag}/bin/' for arm_binary in os.listdir(binary_path): @@ -311,7 +311,12 @@ def main(args) -> int: if __name__ == '__main__': parser = argparse.ArgumentParser( - formatter_class=argparse.ArgumentDefaultsHelpFormatter) + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + epilog=''' + HOST can be set to any of the `host-platform-triplet`s from + depends/README.md for which a release exists. + ''', + ) parser.add_argument('-r', '--remove-dir', action='store_true', help='remove existing directory.') parser.add_argument('-d', '--depends', action='store_true',