Skip to content

Commit

Permalink
TEST GUIX Fix
Browse files Browse the repository at this point in the history
  • Loading branch information
JaredTate committed Mar 28, 2024
1 parent c424208 commit b10e64c
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 139 deletions.
2 changes: 1 addition & 1 deletion ci/test/00_setup_env_mac.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ export XCODE_BUILD_ID=12B45b
export RUN_UNIT_TESTS=false
export RUN_FUNCTIONAL_TESTS=false
export GOAL="deploy"
export BITCOIN_CONFIG="--with-gui --enable-reduce-exports"
export DIGIBYTE_CONFIG="--with-gui --enable-reduce-exports"
64 changes: 28 additions & 36 deletions contrib/devtools/security-check.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#!/usr/bin/env python3
# Copyright (c) 2015-2024 The Bitcoin Core developers
# Copyright (c) 2015-2024 The DigiByte Core developers
# 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.
'''
Expand All @@ -9,14 +8,19 @@
Otherwise the exit status will be 1 and it will log which executables failed which checks.
'''
import sys
from typing import List

import lief
import lief #type:ignore

# temporary constant, to be replaced with lief.ELF.ARCH.RISCV
# https://github.com/lief-project/LIEF/pull/562
LIEF_ELF_ARCH_RISCV = lief.ELF.ARCH(243)

def check_ELF_RELRO(binary) -> bool:
'''
Check for read-only relocations.
GNU_RELRO program header must exist
Dynamic section must have IND_NOW flag
Dynamic section must have BIND_NOW flag
'''
have_gnu_relro = False
for segment in binary.segments:
Expand All @@ -34,7 +38,7 @@ def check_ELF_RELRO(binary) -> bool:
flags = binary.get(lief.ELF.DYNAMIC_TAGS.FLAGS)
if flags.value & lief.ELF.DYNAMIC_FLAGS.BIND_NOW:
have_bindnow = True
except Exception:
except:
have_bindnow = False

return have_gnu_relro and have_bindnow
Expand Down Expand Up @@ -97,6 +101,7 @@ def check_ELF_separate_code(binary):
for segment in binary.segments:
if segment.type == lief.ELF.SEGMENT_TYPES.LOAD:
for section in segment.sections:
assert(section.name not in flags_per_section)
flags_per_section[section.name] = segment.flags
# Spot-check ELF LOAD program header flags per section
# If these sections exist, check them against the expected R/W/E flags
Expand All @@ -113,7 +118,7 @@ def check_ELF_control_flow(binary) -> bool:
main = binary.get_function_address('main')
content = binary.get_content_from_virtual_address(main, 4, lief.Binary.VA_TYPES.AUTO)

if content.tolist() == [243, 15, 30, 250]: # endbr64
if content == [243, 15, 30, 250]: # endbr64
return True
return False

Expand Down Expand Up @@ -142,27 +147,22 @@ def check_PE_control_flow(binary) -> bool:

content = binary.get_content_from_virtual_address(virtual_address, 4, lief.Binary.VA_TYPES.VA)

if content.tolist() == [243, 15, 30, 250]: # endbr64
if content == [243, 15, 30, 250]: # endbr64
return True
return False

def check_PE_Canary(binary) -> bool:
'''
Check for use of stack canary
'''
return binary.has_symbol('__stack_chk_fail')

def check_MACHO_NOUNDEFS(binary) -> bool:
'''
Check for no undefined references.
'''
return binary.header.has(lief.MachO.HEADER_FLAGS.NOUNDEFS)

def check_MACHO_FIXUP_CHAINS(binary) -> bool:
def check_MACHO_LAZY_BINDINGS(binary) -> bool:
'''
Check for use of chained fixups.
Check for no lazy bindings.
We don't use or check for MH_BINDATLOAD. See #18295.
'''
return binary.has_dyld_chained_fixups
return binary.dyld_info.lazy_bind == (0,0)

def check_MACHO_Canary(binary) -> bool:
'''
Expand All @@ -189,17 +189,7 @@ def check_MACHO_control_flow(binary) -> bool:
'''
content = binary.get_content_from_virtual_address(binary.entrypoint, 4, lief.Binary.VA_TYPES.AUTO)

if content.tolist() == [243, 15, 30, 250]: # endbr64
return True
return False

def check_MACHO_branch_protection(binary) -> bool:
'''
Check for branch protection instrumentation
'''
content = binary.get_content_from_virtual_address(binary.entrypoint, 4, lief.Binary.VA_TYPES.AUTO)

if content.tolist() == [95, 36, 3, 213]: # bti
if content == [243, 15, 30, 250]: # endbr64
return True
return False

Expand All @@ -218,13 +208,12 @@ def check_MACHO_branch_protection(binary) -> bool:
('NX', check_NX),
('RELOC_SECTION', check_PE_RELOC_SECTION),
('CONTROL_FLOW', check_PE_control_flow),
('Canary', check_PE_Canary),
]

BASE_MACHO = [
('NOUNDEFS', check_MACHO_NOUNDEFS),
('LAZY_BINDINGS', check_MACHO_LAZY_BINDINGS),
('Canary', check_MACHO_Canary),
('FIXUP_CHAINS', check_MACHO_FIXUP_CHAINS),
]

CHECKS = {
Expand All @@ -233,7 +222,7 @@ def check_MACHO_branch_protection(binary) -> bool:
lief.ARCHITECTURES.ARM: BASE_ELF,
lief.ARCHITECTURES.ARM64: BASE_ELF,
lief.ARCHITECTURES.PPC: BASE_ELF,
# lief.ARCHITECTURES.RISCV: BASE_ELF,
LIEF_ELF_ARCH_RISCV: BASE_ELF,
},
lief.EXE_FORMATS.PE: {
lief.ARCHITECTURES.X86: BASE_PE,
Expand All @@ -242,7 +231,7 @@ def check_MACHO_branch_protection(binary) -> bool:
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)],
lief.ARCHITECTURES.ARM64: BASE_MACHO,
}
}

Expand All @@ -261,11 +250,14 @@ def check_MACHO_branch_protection(binary) -> bool:
continue

if arch == lief.ARCHITECTURES.NONE:
print(f'{filename}: unknown architecture')
retval = 1
continue

failed: list[str] = []
if binary.header.machine_type == LIEF_ELF_ARCH_RISCV:
arch = LIEF_ELF_ARCH_RISCV
else:
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)
Expand Down
99 changes: 40 additions & 59 deletions contrib/devtools/symbol-check.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,48 +11,60 @@
find ../path/to/binaries -type f -executable | xargs python3 contrib/devtools/symbol-check.py
'''
import sys
from typing import List, Dict

import lief
import lief #type:ignore

# Debian 10 (Buster) EOL: 2024. https://wiki.debian.org/LTS
# temporary constant, to be replaced with lief.ELF.ARCH.RISCV
# https://github.com/lief-project/LIEF/pull/562
LIEF_ELF_ARCH_RISCV = lief.ELF.ARCH(243)

# Debian 9 (Stretch) EOL: 2022. https://wiki.debian.org/DebianReleases#Production_Releases
#
# - libgcc version 8.3.0 (https://packages.debian.org/search?suite=buster&arch=any&searchon=names&keywords=libgcc1)
# - libc version 2.28 (https://packages.debian.org/search?suite=buster&arch=any&searchon=names&keywords=libc6)
# - g++ version 6.3.0 (https://packages.debian.org/search?suite=stretch&arch=any&searchon=names&keywords=g%2B%2B)
# - libc version 2.24 (https://packages.debian.org/search?suite=stretch&arch=any&searchon=names&keywords=libc6)
#
# Ubuntu 18.04 (Bionic) EOL: 2028. https://wiki.ubuntu.com/ReleaseTeam
# Ubuntu 16.04 (Xenial) EOL: 2026. https://wiki.ubuntu.com/Releases
#
# - libgcc version 8.4.0 (https://packages.ubuntu.com/bionic/libgcc1)
# - libc version 2.27 (https://packages.ubuntu.com/bionic/libc6)
# - g++ version 5.3.1
# - libc version 2.23
#
# CentOS Stream 8 EOL: 2024. https://wiki.centos.org/About/Product
#
# - libgcc version 8.5.0 (http://mirror.centos.org/centos/8-stream/AppStream/x86_64/os/Packages/)
# - g++ version 8.5.0 (http://mirror.centos.org/centos/8-stream/AppStream/x86_64/os/Packages/)
# - libc version 2.28 (http://mirror.centos.org/centos/8-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),
'GCC': (4,8,0),
'GLIBC': {
lief.ELF.ARCH.x86_64: (2,27),
lief.ELF.ARCH.ARM: (2,27),
lief.ELF.ARCH.AARCH64:(2,27),
lief.ELF.ARCH.PPC64: (2,27),
lief.ELF.ARCH.RISCV: (2,27),
lief.ELF.ARCH.i386: (2,18),
lief.ELF.ARCH.x86_64: (2,18),
lief.ELF.ARCH.ARM: (2,18),
lief.ELF.ARCH.AARCH64:(2,18),
lief.ELF.ARCH.PPC64: (2,18),
LIEF_ELF_ARCH_RISCV: (2,27),
},
'LIBATOMIC': (1,0),
'V': (0,5,0), # xkb (DigiByte-qt only)
}
# See here for a description of _IO_stdin_used:
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=634261#109

# Ignore symbols that are exported as part of every executable
IGNORE_EXPORTS = {
'environ', '_environ', '__environ', '_fini', '_init', 'stdin',
'stdout', 'stderr',
'_edata', '_end', '__end__', '_init', '__bss_start', '__bss_start__', '_bss_end__',
'__bss_end__', '_fini', '_IO_stdin_used', 'stdin', 'stdout', 'stderr',
'environ', '_environ', '__environ',
}

# Expected linker-loader names can be found here:
# https://sourceware.org/glibc/wiki/ABIList?action=recall&rev=16
ELF_INTERPRETER_NAMES: dict[lief.ELF.ARCH, dict[lief.ENDIANNESS, str]] = {
ELF_INTERPRETER_NAMES: Dict[lief.ELF.ARCH, Dict[lief.ENDIANNESS, str]] = {
lief.ELF.ARCH.i386: {
lief.ENDIANNESS.LITTLE: "/lib/ld-linux.so.2",
},
lief.ELF.ARCH.x86_64: {
lief.ENDIANNESS.LITTLE: "/lib64/ld-linux-x86-64.so.2",
},
Expand All @@ -66,37 +78,19 @@
lief.ENDIANNESS.BIG: "/lib64/ld64.so.1",
lief.ENDIANNESS.LITTLE: "/lib64/ld64.so.2",
},
lief.ELF.ARCH.RISCV: {
LIEF_ELF_ARCH_RISCV: {
lief.ENDIANNESS.LITTLE: "/lib/ld-linux-riscv64-lp64d.so.1",
},
}

ELF_ABIS: dict[lief.ELF.ARCH, dict[lief.ENDIANNESS, list[int]]] = {
lief.ELF.ARCH.x86_64: {
lief.ENDIANNESS.LITTLE: [3,2,0],
},
lief.ELF.ARCH.ARM: {
lief.ENDIANNESS.LITTLE: [3,2,0],
},
lief.ELF.ARCH.AARCH64: {
lief.ENDIANNESS.LITTLE: [3,7,0],
},
lief.ELF.ARCH.PPC64: {
lief.ENDIANNESS.LITTLE: [3,10,0],
lief.ENDIANNESS.BIG: [3,2,0],
},
lief.ELF.ARCH.RISCV: {
lief.ENDIANNESS.LITTLE: [4,15,0],
},
}

# Allowed NEEDED libraries
ELF_ALLOWED_LIBRARIES = {
# digibyted and digibyted-qt
'libgcc_s.so.1', # GCC base support
'libc.so.6', # C library
'libpthread.so.0', # threading
'libm.so.6', # math library
'librt.so.1', # real-time (clock)
'libatomic.so.1',
'ld-linux-x86-64.so.2', # 64-bit dynamic linker
'ld-linux.so.2', # 32-bit dynamic linker
Expand Down Expand Up @@ -156,21 +150,21 @@
'KERNEL32.dll', # win32 base APIs
'msvcrt.dll', # C standard library for MSVC
'SHELL32.dll', # shell API
'USER32.dll', # user interface
'WS2_32.dll', # sockets
# digibyte-qt only
'dwmapi.dll', # desktop window manager
'GDI32.dll', # graphics device interface
'IMM32.dll', # input method editor
'NETAPI32.dll', # network management
'NETAPI32.dll',
'ole32.dll', # component object model
'OLEAUT32.dll', # OLE Automation API
'SHLWAPI.dll', # light weight shell API
'USER32.dll', # user interface
'USERENV.dll', # user management
'UxTheme.dll', # visual style
'USERENV.dll',
'UxTheme.dll',
'VERSION.dll', # version checking
'WINMM.dll', # WinMM audio API
'WTSAPI32.dll', # Remote Desktop
'WTSAPI32.dll',
}

def check_version(max_versions, version, arch) -> bool:
Expand Down Expand Up @@ -206,7 +200,7 @@ def check_exported_symbols(binary) -> bool:
if not symbol.exported:
continue
name = symbol.name
if binary.header.machine_type == lief.ELF.ARCH.RISCV or name in IGNORE_EXPORTS:
if binary.header.machine_type == LIEF_ELF_ARCH_RISCV or name in IGNORE_EXPORTS:
continue
print(f'{binary.name}: export of symbol {name} not allowed!')
ok = False
Expand All @@ -230,17 +224,12 @@ 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 == [10,15,0]:
return True
return False

def check_MACHO_sdk(binary) -> bool:
if binary.build_version.sdk == [14, 0, 0]:
return True
return False

def check_MACHO_ld64(binary) -> bool:
if binary.build_version.tools[0].version == [711, 0, 0]:
if binary.build_version.sdk == [11, 0, 0]:
return True
return False

Expand All @@ -264,25 +253,17 @@ def check_ELF_interpreter(binary) -> bool:

return binary.concrete.interpreter == expected_interpreter

def check_ELF_ABI(binary) -> bool:
expected_abi = ELF_ABIS[binary.header.machine_type][binary.abstract.header.endianness]
note = binary.concrete.get(lief.ELF.NOTE_TYPES.ABI_TAG)
assert note.details.abi == lief.ELF.NOTE_ABIS.LINUX
return note.details.version == expected_abi

CHECKS = {
lief.EXE_FORMATS.ELF: [
('IMPORTED_SYMBOLS', check_imported_symbols),
('EXPORTED_SYMBOLS', check_exported_symbols),
('LIBRARY_DEPENDENCIES', check_ELF_libraries),
('INTERPRETER_NAME', check_ELF_interpreter),
('ABI', check_ELF_ABI),
],
lief.EXE_FORMATS.MACHO: [
('DYNAMIC_LIBRARIES', check_MACHO_libraries),
('MIN_OS', check_MACHO_min_os),
('SDK', check_MACHO_sdk),
('LD64', check_MACHO_ld64),
],
lief.EXE_FORMATS.PE: [
('DYNAMIC_LIBRARIES', check_PE_libraries),
Expand All @@ -301,7 +282,7 @@ def check_ELF_ABI(binary) -> bool:
retval = 1
continue

failed: list[str] = []
failed: List[str] = []
for (name, func) in CHECKS[etype]:
if not func(binary):
failed.append(name)
Expand Down
Loading

0 comments on commit b10e64c

Please sign in to comment.