3
3
# Distributed under the MIT software license, see the accompanying
4
4
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
5
'''
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.
9
8
10
9
Example usage:
11
10
53
52
}
54
53
READELF_CMD = os .getenv ('READELF' , '/usr/bin/readelf' )
55
54
CPPFILT_CMD = os .getenv ('CPPFILT' , '/usr/bin/c++filt' )
55
+ OBJDUMP_CMD = os .getenv ('OBJDUMP' , '/usr/bin/objdump' )
56
56
OTOOL_CMD = os .getenv ('OTOOL' , '/usr/bin/otool' )
57
57
58
58
# Allowed NEEDED libraries
101
101
'libobjc.A.dylib' , # Objective-C runtime library
102
102
}
103
103
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
+
104
124
class CPPFilt (object ):
105
125
'''
106
126
Demangle C++ symbol names.
@@ -218,6 +238,26 @@ def check_MACHO_libraries(filename) -> bool:
218
238
ok = False
219
239
return ok
220
240
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
+
221
261
CHECKS = {
222
262
'ELF' : [
223
263
('IMPORTED_SYMBOLS' , check_imported_symbols ),
@@ -226,6 +266,9 @@ def check_MACHO_libraries(filename) -> bool:
226
266
],
227
267
'MACHO' : [
228
268
('DYNAMIC_LIBRARIES' , check_MACHO_libraries )
269
+ ],
270
+ 'PE' : [
271
+ ('DYNAMIC_LIBRARIES' , check_PE_libraries )
229
272
]
230
273
}
231
274
0 commit comments