Merge #18395: scripts: add PE dylib checking to symbol-check.py

1a0993ae354c36d6f219e67f82ca8236530d6201 scripts: add PE dylib checking to symbol-check.py (fanquake)

Pull request description:

  Uses `objdump -x` and looks for `DLL Name:` lines. i.e:
  ```bash
  objdump -x src/qt/bitcoin-qt.exe | grep "DLL Name:"
  	DLL Name: ADVAPI32.dll
  	DLL Name: dwmapi.dll
  	DLL Name: GDI32.dll
  	DLL Name: IMM32.dll
  	DLL Name: IPHLPAPI.DLL
  	DLL Name: KERNEL32.dll
  	DLL Name: msvcrt.dll
  	DLL Name: ole32.dll
  	DLL Name: OLEAUT32.dll
  	DLL Name: SHELL32.dll
  	DLL Name: SHLWAPI.dll
  	DLL Name: USER32.dll
  	DLL Name: UxTheme.dll
  	DLL Name: VERSION.dll
  	DLL Name: WINMM.dll
  	DLL Name: WS2_32.dll
  ```

ACKs for top commit:
  dongcarl:
    Concept ACK 1a0993ae354c36d6f219e67f82ca8236530d6201
  hebasto:
    ACK 1a0993ae354c36d6f219e67f82ca8236530d6201, tested on Linux Mint 19.3:

Tree-SHA512: 0099a50e2c616d5239a15cafa9a7c483e9c40244af41549e4738be0f5360f27a2afb956eb50b47cf446b242f4cfc6dc9d111306a056fb83789eefbd71eddabd2
This commit is contained in:
Wladimir J. van der Laan 2020-03-25 15:32:39 +01:00
commit 3e50fdbe4e
No known key found for this signature in database
GPG Key ID: 1E4AED62986CD25D
4 changed files with 53 additions and 4 deletions

View File

@ -109,7 +109,7 @@ 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 we check that the executables are only linked against libraries we allow.
For macOS and Windows we check that the executables are only linked against libraries we allow.
Example usage after a gitian build:

View File

@ -3,9 +3,8 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
'''
A script to check that the (Linux) executables produced by gitian only contain
allowed gcc and glibc version symbols. This makes sure they are still compatible
with the minimum supported Linux distribution versions.
A script to check that the executables produced by gitian only contain
certain symbols and are only linked against allowed libraries.
Example usage:
@ -53,6 +52,7 @@ IGNORE_EXPORTS = {
}
READELF_CMD = os.getenv('READELF', '/usr/bin/readelf')
CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt')
OBJDUMP_CMD = os.getenv('OBJDUMP', '/usr/bin/objdump')
OTOOL_CMD = os.getenv('OTOOL', '/usr/bin/otool')
# Allowed NEEDED libraries
@ -101,6 +101,26 @@ MACHO_ALLOWED_LIBRARIES = {
'libobjc.A.dylib', # Objective-C runtime library
}
PE_ALLOWED_LIBRARIES = {
'ADVAPI32.dll', # security & registry
'IPHLPAPI.DLL', # IP helper API
'KERNEL32.dll', # win32 base APIs
'msvcrt.dll', # C standard library for MSVC
'SHELL32.dll', # shell API
'USER32.dll', # user interface
'WS2_32.dll', # sockets
# bitcoin-qt only
'dwmapi.dll', # desktop window manager
'GDI32.dll', # graphics device interface
'IMM32.dll', # input method editor
'ole32.dll', # component object model
'OLEAUT32.dll', # OLE Automation API
'SHLWAPI.dll', # light weight shell API
'UxTheme.dll',
'VERSION.dll', # version checking
'WINMM.dll', # WinMM audio API
}
class CPPFilt(object):
'''
Demangle C++ symbol names.
@ -218,6 +238,26 @@ def check_MACHO_libraries(filename) -> bool:
ok = False
return ok
def pe_read_libraries(filename) -> List[str]:
p = subprocess.Popen([OBJDUMP_CMD, '-x', filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True)
(stdout, stderr) = p.communicate()
if p.returncode:
raise IOError('Error opening file')
libraries = []
for line in stdout.splitlines():
if 'DLL Name:' in line:
tokens = line.split(': ')
libraries.append(tokens[1])
return libraries
def check_PE_libraries(filename) -> bool:
ok = True
for dylib in pe_read_libraries(filename):
if dylib not in PE_ALLOWED_LIBRARIES:
print('{} is not in ALLOWED_LIBRARIES!'.format(dylib))
ok = False
return ok
CHECKS = {
'ELF': [
('IMPORTED_SYMBOLS', check_imported_symbols),
@ -226,6 +266,9 @@ CHECKS = {
],
'MACHO': [
('DYNAMIC_LIBRARIES', check_MACHO_libraries)
],
'PE' : [
('DYNAMIC_LIBRARIES', check_PE_libraries)
]
}

View File

@ -138,6 +138,7 @@ script: |
CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}"
make ${MAKEOPTS}
make ${MAKEOPTS} -C src check-security
make ${MAKEOPTS} -C src check-symbols
make deploy
make install DESTDIR=${INSTALLPATH}
cp -f --target-directory="${OUTDIR}" ./bitcoin-*-setup-unsigned.exe

View File

@ -703,6 +703,11 @@ if TARGET_DARWIN
$(AM_V_at) OTOOL=$(OTOOL) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
endif
if TARGET_WINDOWS
@echo "Checking Windows dynamic libraries..."
$(AM_V_at) OBJDUMP=$(OBJDUMP) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
endif
if GLIBC_BACK_COMPAT
@echo "Checking glibc back compat..."
$(AM_V_at) READELF=$(READELF) CPPFILT=$(CPPFILT) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)