@@ -33,6 +33,57 @@ const ELF_ALLOWED_LIBRARIES: &[&str] = &[
33
33
"libpython3.9.so.1.0" ,
34
34
] ;
35
35
36
+ const PE_ALLOWED_LIBRARIES : & [ & str ] = & [
37
+ "ADVAPI32.dll" ,
38
+ "api-ms-win-core-path-l1-1-0.dll" ,
39
+ "api-ms-win-crt-conio-l1-1-0.dll" ,
40
+ "api-ms-win-crt-convert-l1-1-0.dll" ,
41
+ "api-ms-win-crt-heap-l1-1-0.dll" ,
42
+ "api-ms-win-crt-environment-l1-1-0.dll" ,
43
+ "api-ms-win-crt-filesystem-l1-1-0.dll" ,
44
+ "api-ms-win-crt-locale-l1-1-0.dll" ,
45
+ "api-ms-win-crt-math-l1-1-0.dll" ,
46
+ "api-ms-win-crt-process-l1-1-0.dll" ,
47
+ "api-ms-win-crt-runtime-l1-1-0.dll" ,
48
+ "api-ms-win-crt-stdio-l1-1-0.dll" ,
49
+ "api-ms-win-crt-string-l1-1-0.dll" ,
50
+ "api-ms-win-crt-time-l1-1-0.dll" ,
51
+ "api-ms-win-crt-utility-l1-1-0.dll" ,
52
+ "bcrypt.dll" ,
53
+ "Cabinet.dll" ,
54
+ "COMCTL32.dll" ,
55
+ "COMDLG32.dll" ,
56
+ "CRYPT32.dll" ,
57
+ "GDI32.dll" ,
58
+ "IMM32.dll" ,
59
+ "IPHLPAPI.DLL" ,
60
+ "KERNEL32.dll" ,
61
+ "msi.dll" ,
62
+ "NETAPI32.dll" ,
63
+ "ole32.dll" ,
64
+ "OLEAUT32.dll" ,
65
+ "RPCRT4.dll" ,
66
+ "SHELL32.dll" ,
67
+ "SHLWAPI.dll" ,
68
+ "USER32.dll" ,
69
+ "USERENV.dll" ,
70
+ "VERSION.dll" ,
71
+ "VCRUNTIME140.dll" ,
72
+ "WINMM.dll" ,
73
+ "WS2_32.dll" ,
74
+ // Our libraries.
75
+ "libcrypto-1_1.dll" ,
76
+ "libcrypto-1_1-x64.dll" ,
77
+ "libffi-7.dll" ,
78
+ "libssl-1_1.dll" ,
79
+ "libssl-1_1-x64.dll" ,
80
+ "python38.dll" ,
81
+ "python39.dll" ,
82
+ "sqlite3.dll" ,
83
+ "tcl86t.dll" ,
84
+ "tk86t.dll" ,
85
+ ] ;
86
+
36
87
lazy_static ! {
37
88
static ref MACHO_ALLOWED_DYLIBS : Vec <MachOAllowedDylib > = {
38
89
[
@@ -170,11 +221,23 @@ fn validate_macho(path: &Path, macho: &goblin::mach::MachO, bytes: &[u8]) -> Res
170
221
Ok ( errors)
171
222
}
172
223
173
- fn validate_distribution ( path : & Path ) -> Result < Vec < String > > {
224
+ fn validate_pe ( path : & Path , pe : & goblin:: pe:: PE ) -> Result < Vec < String > > {
225
+ let mut errors = vec ! [ ] ;
226
+
227
+ for lib in & pe. libraries {
228
+ if !PE_ALLOWED_LIBRARIES . contains ( lib) {
229
+ errors. push ( format ! ( "{} loads illegal library {}" , path. display( ) , lib) ) ;
230
+ }
231
+ }
232
+
233
+ Ok ( errors)
234
+ }
235
+
236
+ fn validate_distribution ( dist_path : & Path ) -> Result < Vec < String > > {
174
237
let mut errors = vec ! [ ] ;
175
238
176
- let fh =
177
- std :: fs :: File :: open ( & path ) . with_context ( || format ! ( "unable to open {}" , path . display( ) ) ) ?;
239
+ let fh = std :: fs :: File :: open ( & dist_path )
240
+ . with_context ( || format ! ( "unable to open {}" , dist_path . display( ) ) ) ?;
178
241
179
242
let reader = std:: io:: BufReader :: new ( fh) ;
180
243
let dctx = zstd:: stream:: Decoder :: new ( reader) ?;
@@ -200,6 +263,14 @@ fn validate_distribution(path: &Path) -> Result<Vec<String>> {
200
263
errors. push ( format ! ( "unexpected fat mach-o binary: {}" , path. display( ) ) ) ;
201
264
}
202
265
} ,
266
+ goblin:: Object :: PE ( pe) => {
267
+ // We don't care about the wininst-*.exe distutils executables.
268
+ if path. to_string_lossy ( ) . contains ( "wininst-" ) {
269
+ continue ;
270
+ }
271
+
272
+ errors. extend ( validate_pe ( path. as_ref ( ) , & pe) ?) ;
273
+ }
203
274
_ => { }
204
275
}
205
276
}
0 commit comments