Skip to content

Commit 1a0993a

Browse files
committed
scripts: add PE dylib checking to symbol-check.py
1 parent 5504703 commit 1a0993a

File tree

4 files changed

+53
-4
lines changed

4 files changed

+53
-4
lines changed

contrib/devtools/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ certain symbols and are only linked against allowed libraries.
109109
For Linux this means checking for allowed gcc, glibc and libstdc++ version symbols.
110110
This makes sure they are still compatible with the minimum supported distribution versions.
111111

112-
For macOS we check that the executables are only linked against libraries we allow.
112+
For macOS and Windows we check that the executables are only linked against libraries we allow.
113113

114114
Example usage after a gitian build:
115115

contrib/devtools/symbol-check.py

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
# Distributed under the MIT software license, see the accompanying
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
55
'''
6-
A script to check that the (Linux) executables produced by gitian only contain
7-
allowed gcc and glibc version symbols. This makes sure they are still compatible
8-
with the minimum supported Linux distribution versions.
6+
A script to check that the executables produced by gitian only contain
7+
certain symbols and are only linked against allowed libraries.
98
109
Example usage:
1110
@@ -53,6 +52,7 @@
5352
}
5453
READELF_CMD = os.getenv('READELF', '/usr/bin/readelf')
5554
CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt')
55+
OBJDUMP_CMD = os.getenv('OBJDUMP', '/usr/bin/objdump')
5656
OTOOL_CMD = os.getenv('OTOOL', '/usr/bin/otool')
5757

5858
# Allowed NEEDED libraries
@@ -101,6 +101,26 @@
101101
'libobjc.A.dylib', # Objective-C runtime library
102102
}
103103

104+
PE_ALLOWED_LIBRARIES = {
105+
'ADVAPI32.dll', # security & registry
106+
'IPHLPAPI.DLL', # IP helper API
107+
'KERNEL32.dll', # win32 base APIs
108+
'msvcrt.dll', # C standard library for MSVC
109+
'SHELL32.dll', # shell API
110+
'USER32.dll', # user interface
111+
'WS2_32.dll', # sockets
112+
# bitcoin-qt only
113+
'dwmapi.dll', # desktop window manager
114+
'GDI32.dll', # graphics device interface
115+
'IMM32.dll', # input method editor
116+
'ole32.dll', # component object model
117+
'OLEAUT32.dll', # OLE Automation API
118+
'SHLWAPI.dll', # light weight shell API
119+
'UxTheme.dll',
120+
'VERSION.dll', # version checking
121+
'WINMM.dll', # WinMM audio API
122+
}
123+
104124
class CPPFilt(object):
105125
'''
106126
Demangle C++ symbol names.
@@ -218,6 +238,26 @@ def check_MACHO_libraries(filename) -> bool:
218238
ok = False
219239
return ok
220240

241+
def pe_read_libraries(filename) -> List[str]:
242+
p = subprocess.Popen([OBJDUMP_CMD, '-x', filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, universal_newlines=True)
243+
(stdout, stderr) = p.communicate()
244+
if p.returncode:
245+
raise IOError('Error opening file')
246+
libraries = []
247+
for line in stdout.splitlines():
248+
if 'DLL Name:' in line:
249+
tokens = line.split(': ')
250+
libraries.append(tokens[1])
251+
return libraries
252+
253+
def check_PE_libraries(filename) -> bool:
254+
ok = True
255+
for dylib in pe_read_libraries(filename):
256+
if dylib not in PE_ALLOWED_LIBRARIES:
257+
print('{} is not in ALLOWED_LIBRARIES!'.format(dylib))
258+
ok = False
259+
return ok
260+
221261
CHECKS = {
222262
'ELF': [
223263
('IMPORTED_SYMBOLS', check_imported_symbols),
@@ -226,6 +266,9 @@ def check_MACHO_libraries(filename) -> bool:
226266
],
227267
'MACHO': [
228268
('DYNAMIC_LIBRARIES', check_MACHO_libraries)
269+
],
270+
'PE' : [
271+
('DYNAMIC_LIBRARIES', check_PE_libraries)
229272
]
230273
}
231274

contrib/gitian-descriptors/gitian-win.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ script: |
145145
CONFIG_SITE=${BASEPREFIX}/${i}/share/config.site ./configure --prefix=/ --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} CFLAGS="${HOST_CFLAGS}" CXXFLAGS="${HOST_CXXFLAGS}"
146146
make ${MAKEOPTS}
147147
make ${MAKEOPTS} -C src check-security
148+
make ${MAKEOPTS} -C src check-symbols
148149
make deploy
149150
make install DESTDIR=${INSTALLPATH}
150151
cp -f --target-directory="${OUTDIR}" ./bitcoin-*-setup-unsigned.exe

src/Makefile.am

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,11 @@ if TARGET_DARWIN
703703
$(AM_V_at) OTOOL=$(OTOOL) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
704704
endif
705705

706+
if TARGET_WINDOWS
707+
@echo "Checking Windows dynamic libraries..."
708+
$(AM_V_at) OBJDUMP=$(OBJDUMP) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
709+
endif
710+
706711
if GLIBC_BACK_COMPAT
707712
@echo "Checking glibc back compat..."
708713
$(AM_V_at) READELF=$(READELF) CPPFILT=$(CPPFILT) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)

0 commit comments

Comments
 (0)