44# file COPYING or http://www.opensource.org/licenses/mit-license.php.
55'''
66A script to check that the (Linux) release executables only contain
7- allowed gcc and glibc version symbols. This makes sure they are still compatible
8- with the minimum supported Linux distribution versions.
7+ certain symbols and are only linked against allowed libraries.
98
109Example usage:
1110
5756'environ' , '_environ' , '__environ' ,
5857}
5958CPPFILT_CMD = os .getenv ('CPPFILT' , '/usr/bin/c++filt' )
59+ OBJDUMP_CMD = os .getenv ('OBJDUMP' , '/usr/bin/objdump' )
6060OTOOL_CMD = os .getenv ('OTOOL' , '/usr/bin/otool' )
6161
6262# Allowed NEEDED libraries
107107'QuartzCore' , # animation
108108}
109109
110+ PE_ALLOWED_LIBRARIES = {
111+ 'ADVAPI32.dll' , # security & registry
112+ 'IPHLPAPI.DLL' , # IP helper API
113+ 'KERNEL32.dll' , # win32 base APIs
114+ 'msvcrt.dll' , # C standard library for MSVC
115+ 'SHELL32.dll' , # shell API
116+ 'USER32.dll' , # user interface
117+ 'WS2_32.dll' , # sockets
118+ 'bcrypt.dll' ,
119+ # bitcoin-qt only
120+ 'dwmapi.dll' , # desktop window manager
121+ 'GDI32.dll' , # graphics device interface
122+ 'IMM32.dll' , # input method editor
123+ 'NETAPI32.dll' ,
124+ 'ole32.dll' , # component object model
125+ 'OLEAUT32.dll' , # OLE Automation API
126+ 'SHLWAPI.dll' , # light weight shell API
127+ 'USERENV.dll' ,
128+ 'UxTheme.dll' ,
129+ 'VERSION.dll' , # version checking
130+ 'WINMM.dll' , # WinMM audio API
131+ 'WTSAPI32.dll' ,
132+ }
133+
110134class CPPFilt (object ):
111135 '''
112136 Demangle C++ symbol names.
@@ -200,6 +224,26 @@ def check_MACHO_libraries(filename) -> bool:
200224 ok = False
201225 return ok
202226
227+ def pe_read_libraries (filename ) -> List [str ]:
228+ p = subprocess .Popen ([OBJDUMP_CMD , '-x' , filename ], stdout = subprocess .PIPE , stderr = subprocess .PIPE , stdin = subprocess .PIPE , universal_newlines = True )
229+ (stdout , stderr ) = p .communicate ()
230+ if p .returncode :
231+ raise IOError ('Error opening file' )
232+ libraries = []
233+ for line in stdout .splitlines ():
234+ if 'DLL Name:' in line :
235+ tokens = line .split (': ' )
236+ libraries .append (tokens [1 ])
237+ return libraries
238+
239+ def check_PE_libraries (filename ) -> bool :
240+ ok = True
241+ for dylib in pe_read_libraries (filename ):
242+ if dylib not in PE_ALLOWED_LIBRARIES :
243+ print ('{} is not in ALLOWED_LIBRARIES!' .format (dylib ))
244+ ok = False
245+ return ok
246+
203247CHECKS = {
204248'ELF' : [
205249 ('IMPORTED_SYMBOLS' , check_imported_symbols ),
@@ -208,6 +252,9 @@ def check_MACHO_libraries(filename) -> bool:
208252],
209253'MACHO' : [
210254 ('DYNAMIC_LIBRARIES' , check_MACHO_libraries )
255+ ],
256+ 'PE' : [
257+ ('DYNAMIC_LIBRARIES' , check_PE_libraries )
211258]
212259}
213260
0 commit comments