File: | var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp |
Warning: | line 1436, column 3 Value stored to 'rv' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | /* vim: set ts=2 et sw=2 tw=80: */ |
3 | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | // See |
7 | // https://wiki.mozilla.org/Security/Features/Application_Reputation_Design_Doc |
8 | // for a description of Chrome's implementation of this feature. |
9 | #include "ApplicationReputation.h" |
10 | #include "chrome/common/safe_browsing/csd.pb.h" |
11 | |
12 | #include "nsIArray.h" |
13 | #include "nsIApplicationReputation.h" |
14 | #include "nsIChannel.h" |
15 | #include "nsIHttpChannel.h" |
16 | #include "nsIIOService.h" |
17 | #include "nsIObserverService.h" |
18 | #include "nsISimpleEnumerator.h" |
19 | #include "nsIStreamListener.h" |
20 | #include "nsIStringStream.h" |
21 | #include "nsITimer.h" |
22 | #include "nsIUploadChannel2.h" |
23 | #include "nsIURI.h" |
24 | #include "nsIURL.h" |
25 | #include "nsIUrlClassifierDBService.h" |
26 | #include "nsIURLFormatter.h" |
27 | #include "nsIX509Cert.h" |
28 | #include "nsIX509CertDB.h" |
29 | |
30 | #include "mozilla/ArrayUtils.h" |
31 | #include "mozilla/BasePrincipal.h" |
32 | #include "mozilla/Components.h" |
33 | #include "mozilla/ErrorNames.h" |
34 | #include "mozilla/LoadContext.h" |
35 | #include "mozilla/Preferences.h" |
36 | #include "mozilla/ScopeExit.h" |
37 | #include "mozilla/Services.h" |
38 | #include "mozilla/Telemetry.h" |
39 | #include "mozilla/TimeStamp.h" |
40 | #include "mozilla/intl/LocaleService.h" |
41 | |
42 | #include "nsCOMPtr.h" |
43 | #include "nsDebug.h" |
44 | #include "nsDependentSubstring.h" |
45 | #include "nsError.h" |
46 | #include "nsLocalFileCommon.h" |
47 | #include "nsNetCID.h" |
48 | #include "nsReadableUtils.h" |
49 | #include "nsServiceManagerUtils.h" |
50 | #include "nsString.h" |
51 | #include "nsTArray.h" |
52 | #include "nsThreadUtils.h" |
53 | |
54 | #include "nsIContentPolicy.h" |
55 | #include "nsICryptoHash.h" |
56 | #include "nsILoadInfo.h" |
57 | #include "nsContentUtils.h" |
58 | #include "nsWeakReference.h" |
59 | #include "nsIRedirectHistoryEntry.h" |
60 | |
61 | #include "ApplicationReputationTelemetryUtils.h" |
62 | |
63 | using mozilla::ArrayLength; |
64 | using mozilla::BasePrincipal; |
65 | using mozilla::OriginAttributes; |
66 | using mozilla::Preferences; |
67 | using mozilla::TimeStamp; |
68 | using mozilla::intl::LocaleService; |
69 | using mozilla::Telemetry::Accumulate; |
70 | using mozilla::Telemetry::AccumulateCategorical; |
71 | using safe_browsing::ClientDownloadRequest; |
72 | using safe_browsing::ClientDownloadRequest_CertificateChain; |
73 | using safe_browsing::ClientDownloadRequest_Resource; |
74 | using safe_browsing::ClientDownloadRequest_SignatureInfo; |
75 | |
76 | // Preferences that we need to initialize the query. |
77 | #define PREF_SB_APP_REP_URL"browser.safebrowsing.downloads.remote.url" "browser.safebrowsing.downloads.remote.url" |
78 | #define PREF_SB_MALWARE_ENABLED"browser.safebrowsing.malware.enabled" "browser.safebrowsing.malware.enabled" |
79 | #define PREF_SB_DOWNLOADS_ENABLED"browser.safebrowsing.downloads.enabled" "browser.safebrowsing.downloads.enabled" |
80 | #define PREF_SB_DOWNLOADS_REMOTE_ENABLED"browser.safebrowsing.downloads.remote.enabled" \ |
81 | "browser.safebrowsing.downloads.remote.enabled" |
82 | #define PREF_SB_DOWNLOADS_REMOTE_TIMEOUT"browser.safebrowsing.downloads.remote.timeout_ms" \ |
83 | "browser.safebrowsing.downloads.remote.timeout_ms" |
84 | #define PREF_DOWNLOAD_BLOCK_TABLE"urlclassifier.downloadBlockTable" "urlclassifier.downloadBlockTable" |
85 | #define PREF_DOWNLOAD_ALLOW_TABLE"urlclassifier.downloadAllowTable" "urlclassifier.downloadAllowTable" |
86 | |
87 | // Preferences that are needed to action the verdict. |
88 | #define PREF_BLOCK_DANGEROUS"browser.safebrowsing.downloads.remote.block_dangerous" \ |
89 | "browser.safebrowsing.downloads.remote.block_dangerous" |
90 | #define PREF_BLOCK_DANGEROUS_HOST"browser.safebrowsing.downloads.remote.block_dangerous_host" \ |
91 | "browser.safebrowsing.downloads.remote.block_dangerous_host" |
92 | #define PREF_BLOCK_POTENTIALLY_UNWANTED"browser.safebrowsing.downloads.remote.block_potentially_unwanted" \ |
93 | "browser.safebrowsing.downloads.remote.block_potentially_unwanted" |
94 | #define PREF_BLOCK_UNCOMMON"browser.safebrowsing.downloads.remote.block_uncommon" \ |
95 | "browser.safebrowsing.downloads.remote.block_uncommon" |
96 | |
97 | // MOZ_LOG=ApplicationReputation:5 |
98 | mozilla::LazyLogModule ApplicationReputationService::prlog( |
99 | "ApplicationReputation"); |
100 | #define LOG(args)do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, MOZ_LOG_EXPAND_ARGS args); } } while (0) \ |
101 | MOZ_LOG(ApplicationReputationService::prlog, mozilla::LogLevel::Debug, args)do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, MOZ_LOG_EXPAND_ARGS args); } } while (0) |
102 | #define LOG_ENABLED()(__builtin_expect(!!(mozilla::detail::log_test(ApplicationReputationService ::prlog, mozilla::LogLevel::Debug)), 0)) \ |
103 | MOZ_LOG_TEST(ApplicationReputationService::prlog, mozilla::LogLevel::Debug)(__builtin_expect(!!(mozilla::detail::log_test(ApplicationReputationService ::prlog, mozilla::LogLevel::Debug)), 0)) |
104 | |
105 | /** |
106 | * Our detection of executable/binary files uses 3 lists: |
107 | * - kNonBinaryExecutables (below) |
108 | * - kBinaryFileExtensions (below) |
109 | * - sExecutableExts (in nsLocalFileCommon) |
110 | * |
111 | * On Windows, the `sExecutableExts` list is used to determine whether files |
112 | * count as executable. For executable files, we will not offer an "open with" |
113 | * option when downloading, only "save as". |
114 | * |
115 | * On all platforms, the combination of these lists is used to determine |
116 | * whether files should be subject to application reputation checks. |
117 | * Specifically, all files with extensions that: |
118 | * - are in kBinaryFileExtensions, or |
119 | * - are in sExecutableExts **and not in kNonBinaryExecutables** |
120 | * |
121 | * will be subject to checks. |
122 | * |
123 | * There are tests that verify that these lists are sorted and that extensions |
124 | * never appear in both the sExecutableExts and kBinaryFileExtensions lists. |
125 | * |
126 | * When adding items to any lists: |
127 | * - please prefer adding to sExecutableExts unless it is imperative users can |
128 | * (potentially automatically!) open such files with a helper application |
129 | * without first saving them (and that outweighs any associated risk). |
130 | * - if adding executable items that shouldn't be submitted to apprep servers, |
131 | * add them to sExecutableExts and also to kNonBinaryExecutables. |
132 | * - always add an associated comment in the kBinaryFileExtensions list. Add |
133 | * a commented-out entry with an `exec` annotation if you add the actual |
134 | * entry in sExecutableExts. |
135 | * |
136 | * When removing items please consider whether items should still be in the |
137 | * sExecutableExts list even if removing them from the kBinaryFileExtensions |
138 | * list, and vice versa. |
139 | * |
140 | * Note that there is a GTest that does its best to check some of these |
141 | * invariants that you'll likely need to update if you're modifying these |
142 | * lists. |
143 | */ |
144 | |
145 | // Items that are in sExecutableExts but shouldn't be submitted for application |
146 | // reputation checks. |
147 | /* static */ |
148 | const char* const ApplicationReputationService::kNonBinaryExecutables[] = { |
149 | // clang-format off |
150 | ".ad", |
151 | ".afploc", |
152 | ".air", |
153 | ".atloc", |
154 | ".ftploc", |
155 | // clang-format on |
156 | }; |
157 | |
158 | // Items that should be submitted for application reputation checks that users |
159 | // are able to open immediately (without first saving and then finding the |
160 | // file). If users shouldn't be able to open them immediately, add to |
161 | // sExecutableExts instead (see also the docstring comment above!). |
162 | /* static */ |
163 | const char* const ApplicationReputationService::kBinaryFileExtensions[] = { |
164 | // Originally extracted from the "File Type Policies" Chrome extension |
165 | // Items listed with an `exec` comment are in the sExecutableExts list in |
166 | // nsLocalFileCommon.h . |
167 | //".001", |
168 | //".7z", |
169 | //".ace", |
170 | //".accda", exec // MS Access database |
171 | //".accdb", exec // MS Access database |
172 | //".accde", exec // MS Access database |
173 | //".accdr", exec // MS Access database |
174 | ".action", // Mac script |
175 | //".ad", exec // Windows |
176 | //".ade", exec // MS Access |
177 | //".adp", exec // MS Access |
178 | //".air", exec // Adobe AIR installer; excluded from apprep checks. |
179 | ".apk", // Android package |
180 | //".app", exec // Executable application |
181 | ".applescript", |
182 | //".application", exec // MS ClickOnce |
183 | //".appref-ms", exec // MS ClickOnce |
184 | //".appx", exec |
185 | //".appxbundle", exec |
186 | //".arc", |
187 | //".arj", |
188 | ".as", // Mac archive |
189 | //".asp", exec // Windows Server script |
190 | ".asx", // Windows Media Player |
191 | //".b64", |
192 | //".balz", |
193 | //".bas", exec // Basic script |
194 | ".bash", // Linux shell |
195 | //".bat", exec // Windows shell |
196 | //".bhx", |
197 | ".bin", |
198 | ".btapp", // uTorrent and Transmission |
199 | ".btinstall", // uTorrent and Transmission |
200 | ".btkey", // uTorrent and Transmission |
201 | ".btsearch", // uTorrent and Transmission |
202 | ".btskin", // uTorrent and Transmission |
203 | ".bz", // Linux archive (bzip) |
204 | ".bz2", // Linux archive (bzip2) |
205 | ".bzip2", // Linux archive (bzip2) |
206 | ".cab", // Windows archive |
207 | ".caction", // Automator action |
208 | ".cdr", // Mac disk image |
209 | //".cer", exec // Signed certificate file |
210 | ".cfg", // Windows |
211 | ".chi", // Windows Help |
212 | //".chm", exec // Windows Help |
213 | ".class", // Java |
214 | //".cmd", exec // Windows executable |
215 | //".com", exec // Windows executable |
216 | ".command", // Mac script |
217 | ".configprofile", // Configuration file for Apple systems |
218 | ".cpgz", // Mac archive |
219 | ".cpi", // Control Panel Item. Executable used for adding icons |
220 | // to Control Panel |
221 | //".cpio", |
222 | //".cpl", exec // Windows executable |
223 | //".crt", exec // Windows signed certificate |
224 | ".crx", // Chrome extensions |
225 | ".csh", // Linux shell |
226 | //".csv", |
227 | ".dart", // Mac disk image |
228 | ".dc42", // Apple DiskCopy Image |
229 | ".deb", // Linux package |
230 | ".definition", // Automator action |
231 | ".desktop", // A shortcut that runs other files |
232 | //".der", exec // Signed certificate |
233 | ".dex", // Android |
234 | ".dht", // HTML |
235 | ".dhtm", // HTML |
236 | ".dhtml", // HTML |
237 | //".diagcab", exec // Executable windows archive, like .cab |
238 | ".diskcopy42", // Apple DiskCopy Image |
239 | ".dll", // Windows executable |
240 | ".dmg", // Mac disk image |
241 | ".dmgpart", // Mac disk image |
242 | ".doc", // MS Office |
243 | ".docb", // MS Office |
244 | ".docm", // MS Word |
245 | ".docx", // MS Word |
246 | ".dot", // MS Word |
247 | ".dotm", // MS Word |
248 | ".dott", // MS Office |
249 | ".dotx", // MS Word |
250 | ".drv", // Windows driver |
251 | ".dvdr", // Mac Disk image |
252 | ".dylib", // Mach object dynamic library file |
253 | ".efi", // Firmware |
254 | ".eml", // MS Outlook |
255 | //".exe", exec // Windows executable |
256 | //".fat", |
257 | //".fileloc", exec // Apple finder internet location data file |
258 | ".fon", // Windows font |
259 | //".fxp", exec // MS FoxPro |
260 | ".gadget", // Windows |
261 | //".gif", |
262 | ".grp", // Windows |
263 | ".gz", // Linux archive (gzip) |
264 | ".gzip", // Linux archive (gzip) |
265 | ".hfs", // Mac disk image |
266 | //".hlp", exec // Windows Help |
267 | ".hqx", // Mac archive |
268 | //".hta", exec // HTML trusted application |
269 | ".htm", ".html", |
270 | ".htt", // MS HTML template |
271 | //".ica", |
272 | ".img", // Mac disk image |
273 | ".imgpart", // Mac disk image |
274 | //".inf", exec // Windows installer |
275 | //".inetloc", exec // Apple finder internet location data file |
276 | ".ini", // Generic config file |
277 | //".ins", exec // IIS config |
278 | ".internetconnect", // Configuration file for Apple system |
279 | //".inx", // InstallShield |
280 | ".iso", // CD image |
281 | //".isp", exec // IIS config |
282 | //".isu", // InstallShield |
283 | //".jar", exec // Java |
284 | #ifndef MOZ_ESR |
285 | //".jnlp", exec // Java |
286 | #endif |
287 | //".job", // Windows |
288 | //".jpg", |
289 | //".jpeg", |
290 | //".js", exec // JavaScript script |
291 | //".jse", exec // JScript |
292 | ".ksh", // Linux shell |
293 | //".lha", |
294 | //".lnk", exec // Windows |
295 | ".local", // Windows |
296 | //".lpaq1", |
297 | //".lpaq5", |
298 | //".lpaq8", |
299 | //".lzh", |
300 | //".lzma", |
301 | //".mad", exec // MS Access |
302 | //".maf", exec // MS Access |
303 | //".mag", exec // MS Access |
304 | //".mam", exec // MS Access |
305 | ".manifest", // Windows |
306 | //".maq", exec // MS Access |
307 | //".mar", exec // MS Access |
308 | //".mas", exec // MS Access |
309 | //".mat", exec // MS Access |
310 | //".mau", exec // Media attachment |
311 | //".mav", exec // MS Access |
312 | //".maw", exec // MS Access |
313 | //".mda", exec // MS Access |
314 | //".mdb", exec // MS Access |
315 | //".mde", exec // MS Access |
316 | //".mdt", exec // MS Access |
317 | //".mdw", exec // MS Access |
318 | //".mdz", exec // MS Access |
319 | ".mht", // MS HTML |
320 | ".mhtml", // MS HTML |
321 | ".mim", // MS Mail |
322 | //".mkv", |
323 | ".mmc", // MS Office |
324 | ".mobileconfig", // Configuration file for Apple systems |
325 | ".mof", // Windows |
326 | //".mov", |
327 | //".mp3", |
328 | //".mp4", |
329 | ".mpkg", // Mac installer |
330 | //".msc", exec // Windows executable |
331 | ".msg", // MS Outlook |
332 | //".msh", exec // Windows shell |
333 | //".msh1", exec // Windows shell |
334 | //".msh1xml", exec // Windows shell |
335 | //".msh2", exec // Windows shell |
336 | //".msh2xml", exec // Windows shell |
337 | //".mshxml", exec // Windows |
338 | //".msi", exec // Windows installer |
339 | //".msix", exec // Windows installer |
340 | //".msixbundle", exec // Windows installer |
341 | //".msp", exec // Windows installer |
342 | //".mst", exec // Windows installer |
343 | ".ndif", // Mac disk image |
344 | ".networkconnect", // Configuration file for Apple systems |
345 | //".ntfs", // 7z |
346 | ".ocx", // ActiveX |
347 | //".ops", exec // MS Office |
348 | ".osas", // AppleScript |
349 | ".osax", // AppleScript |
350 | //".out", // Linux binary |
351 | ".oxt", // OpenOffice extension, can execute arbitrary code |
352 | //".package", |
353 | //".paf", // PortableApps package |
354 | //".paq8f", |
355 | //".paq8jd", |
356 | //".paq8l", |
357 | //".paq8o", |
358 | ".partial", // Downloads |
359 | ".pax", // Mac archive |
360 | //".pcd", exec // Microsoft Visual Test |
361 | ".pdf", // Adobe Acrobat |
362 | //".pea", |
363 | ".pet", // Linux package |
364 | //".pif", exec // Windows |
365 | ".pkg", // Mac installer |
366 | ".pl", // Perl script |
367 | //".plg", exec // MS Visual Studio |
368 | //".png", |
369 | ".pot", // MS PowerPoint |
370 | ".potm", // MS PowerPoint |
371 | ".potx", // MS PowerPoint |
372 | ".ppam", // MS PowerPoint |
373 | ".pps", // MS PowerPoint |
374 | ".ppsm", // MS PowerPoint |
375 | ".ppsx", // MS PowerPoint |
376 | ".ppt", // MS PowerPoint |
377 | ".pptm", // MS PowerPoint |
378 | ".pptx", // MS PowerPoint |
379 | //".prf", exec // MS Outlook |
380 | //".prg", exec // Windows |
381 | ".ps1", // Windows shell |
382 | ".ps1xml", // Windows shell |
383 | ".ps2", // Windows shell |
384 | ".ps2xml", // Windows shell |
385 | ".psc1", // Windows shell |
386 | ".psc2", // Windows shell |
387 | //".pst", exec // MS Outlook |
388 | ".pup", // Linux package |
389 | ".py", // Python script |
390 | ".pyc", // Python binary |
391 | ".pyd", // Equivalent of a DLL, for python libraries |
392 | ".pyo", // Compiled python code |
393 | ".pyw", // Python GUI |
394 | //".quad", |
395 | //".r00", |
396 | //".r01", |
397 | //".r02", |
398 | //".r03", |
399 | //".r04", |
400 | //".r05", |
401 | //".r06", |
402 | //".r07", |
403 | //".r08", |
404 | //".r09", |
405 | //".r10", |
406 | //".r11", |
407 | //".r12", |
408 | //".r13", |
409 | //".r14", |
410 | //".r15", |
411 | //".r16", |
412 | //".r17", |
413 | //".r18", |
414 | //".r19", |
415 | //".r20", |
416 | //".r21", |
417 | //".r22", |
418 | //".r23", |
419 | //".r24", |
420 | //".r25", |
421 | //".r26", |
422 | //".r27", |
423 | //".r28", |
424 | //".r29", |
425 | //".rar", |
426 | ".rb", // Ruby script |
427 | //".reg", exec // Windows Registry |
428 | ".rels", // MS Office |
429 | //".rgs", // Windows Registry |
430 | ".rpm", // Linux package |
431 | ".rtf", // MS Office |
432 | //".run", // Linux shell |
433 | //".scf", exec // Windows shell |
434 | ".scpt", // AppleScript |
435 | ".scptd", // AppleScript |
436 | //".scr", exec // Windows |
437 | //".sct", exec // Windows shell |
438 | ".search-ms", // Windows |
439 | ".seplugin", // AppleScript |
440 | ".service", // Systemd service unit file |
441 | //".settingcontent-ms", exec // Windows settings |
442 | ".sh", // Linux shell |
443 | ".shar", // Linux shell |
444 | //".shb", exec // Windows |
445 | //".shs", exec // Windows shell |
446 | ".sht", // HTML |
447 | ".shtm", // HTML |
448 | ".shtml", // HTML |
449 | ".sldm", // MS PowerPoint |
450 | ".sldx", // MS PowerPoint |
451 | ".slk", // MS Excel |
452 | ".slp", // Linux package |
453 | ".smi", // Mac disk image |
454 | ".sparsebundle", // Mac disk image |
455 | ".sparseimage", // Mac disk image |
456 | ".spl", // Adobe Flash |
457 | //".squashfs", |
458 | ".svg", |
459 | ".swf", // Adobe Flash |
460 | ".swm", // Windows Imaging |
461 | ".sys", // Windows |
462 | ".tar", // Linux archive |
463 | ".taz", // Linux archive (bzip2) |
464 | ".tbz", // Linux archive (bzip2) |
465 | ".tbz2", // Linux archive (bzip2) |
466 | ".tcsh", // Linux shell |
467 | //".tif", |
468 | ".tgz", // Linux archive (gzip) |
469 | //".toast", // Roxio disk image |
470 | ".torrent", // Bittorrent |
471 | ".tpz", // Linux archive (gzip) |
472 | //".txt", |
473 | ".txz", // Linux archive (xz) |
474 | ".tz", // Linux archive (gzip) |
475 | //".u3p", // U3 Smart Apps |
476 | ".udf", // MS Excel |
477 | ".udif", // Mac disk image |
478 | //".url", exec // Windows |
479 | //".uu", |
480 | //".uue", |
481 | //".vb", exec // Visual Basic script |
482 | //".vbe", exec // Visual Basic script |
483 | //".vbs", exec // Visual Basic script |
484 | //".vbscript", // Visual Basic script |
485 | //".vdx", exec // MS Visio |
486 | ".vhd", // Windows virtual hard drive |
487 | ".vhdx", // Windows virtual hard drive |
488 | ".vmdk", // VMware virtual disk |
489 | //".vsd", exec // MS Visio |
490 | //".vsdm", exec // MS Visio |
491 | //".vsdx", exec // MS Visio |
492 | //".vsmacros", exec // MS Visual Studio |
493 | //".vss", exec // MS Visio |
494 | //".vssm", exec // MS Visio |
495 | //".vssx", exec // MS Visio |
496 | //".vst", exec // MS Visio |
497 | //".vstm", exec // MS Visio |
498 | //".vstx", exec // MS Visio |
499 | //".vsw", exec // MS Visio |
500 | //".vsx", exec // MS Visio |
501 | //".vtx", exec // MS Visio |
502 | //".wav", |
503 | //".webloc", // MacOS website location file |
504 | //".webp", |
505 | ".website", // Windows |
506 | ".wflow", // Automator action |
507 | ".wim", // Windows Imaging |
508 | ".workflow", // Mac Automator |
509 | //".wrc", // FreeArc archive |
510 | //".ws", exec // Windows script |
511 | //".wsc", exec // Windows script |
512 | //".wsf", exec // Windows script |
513 | //".wsh", exec // Windows script |
514 | ".xar", // MS Excel |
515 | ".xbap", // XAML Browser Application |
516 | ".xht", ".xhtm", ".xhtml", |
517 | ".xip", // Mac archive |
518 | ".xla", // MS Excel |
519 | ".xlam", // MS Excel |
520 | ".xldm", // MS Excel |
521 | //".xll", exec // MS Excel |
522 | ".xlm", // MS Excel |
523 | ".xls", // MS Excel |
524 | ".xlsb", // MS Excel |
525 | ".xlsm", // MS Excel |
526 | ".xlsx", // MS Excel |
527 | ".xlt", // MS Excel |
528 | ".xltm", // MS Excel |
529 | ".xltx", // MS Excel |
530 | ".xlw", // MS Excel |
531 | ".xml", // MS Excel |
532 | ".xnk", // MS Exchange |
533 | //".xrm-ms", exec // Windows |
534 | ".xsd", // XML schema definition |
535 | ".xsl", // XML Stylesheet |
536 | //".xxe", |
537 | ".xz", // Linux archive (xz) |
538 | ".z", // InstallShield |
539 | #ifdef XP_WIN // disable on Mac/Linux, see 1167493 |
540 | ".zip", // Generic archive |
541 | #endif |
542 | ".zipx", // WinZip |
543 | //".zpaq", |
544 | }; |
545 | |
546 | static const char* const kMozNonBinaryExecutables[] = { |
547 | ".001", ".7z", ".ace", ".arc", ".arj", ".b64", ".balz", |
548 | ".bhx", ".cpio", ".fat", ".lha", ".lpaq1", ".lpaq5", ".lpaq8", |
549 | ".lzh", ".lzma", ".ntfs", ".paq8f", ".paq8jd", ".paq8l", ".paq8o", |
550 | ".pea", ".quad", ".r00", ".r01", ".r02", ".r03", ".r04", |
551 | ".r05", ".r06", ".r07", ".r08", ".r09", ".r10", ".r11", |
552 | ".r12", ".r13", ".r14", ".r15", ".r16", ".r17", ".r18", |
553 | ".r19", ".r20", ".r21", ".r22", ".r23", ".r24", ".r25", |
554 | ".r26", ".r27", ".r28", ".r29", ".rar", ".squashfs", ".uu", |
555 | ".uue", ".wrc", ".xxe", ".zpaq", ".toast", |
556 | }; |
557 | |
558 | static const char* const kSafeFileExtensions[] = { |
559 | ".jpg", ".jpeg", ".mp3", ".mp4", ".png", ".csv", ".ica", |
560 | ".gif", ".txt", ".package", ".tif", ".webp", ".mkv", ".wav", |
561 | ".mov", ".paf", ".vbscript", ".ad", ".inx", ".isu", ".job", |
562 | ".rgs", ".u3p", ".out", ".run", ".bmp", ".css", ".ehtml", |
563 | ".flac", ".ico", ".jfif", ".m4a", ".m4v", ".mpeg", ".mpg", |
564 | ".oga", ".ogg", ".ogm", ".ogv", ".opus", ".pjp", ".pjpeg", |
565 | ".svgz", ".text", ".tiff", ".weba", ".webm", ".xbm", |
566 | }; |
567 | |
568 | enum class LookupType { AllowlistOnly, BlocklistOnly, BothLists }; |
569 | |
570 | // Define the reasons that download protection service accepts or blocks this |
571 | // download. This is now used for telemetry purposes and xpcshell test. Please |
572 | // also update the xpcshell-test if a reason is added. |
573 | // |
574 | // LocalWhitelist : URL is found in the local whitelist |
575 | // LocalBlocklist : URL is found in the local blocklist |
576 | // NonBinary : The downloaded non-binary file is not found in the |
577 | // local blocklist VerdictSafe : Remote lookup reports the download is |
578 | // safe VerdictUnknown : Remote lookup reports unknown, we treat this as a |
579 | // safe download VerdictDangerous : Remote lookup reports the download is |
580 | // dangerous VerdictDangerousHost : Remote lookup reports the download is from a |
581 | // dangerous host VerdictUnwanted : Remote lookup reports the download is |
582 | // potentially unwatned VerdictUncommon : Remote lookup reports the |
583 | // download is uncommon VerdictUnrecognized : The verdict type from remote |
584 | // lookup is not defined in the csd.proto DangerousPrefOff : The download is |
585 | // dangerous, but the corresponding preference is off DangerousHostPrefOff : The |
586 | // download is from a dangerous host, but the corresponding preference is off |
587 | // UnwantedPrefOff : The download is potentially unwanted, but the |
588 | // corresponding preference is off UncommonPrefOff : The download us |
589 | // uncommon, but the coressponding preference is off NetworkError : |
590 | // There is an error while requesting remote lookup RemoteLookupDisabled : |
591 | // Remote lookup is disabled or the remote lookup URL is empty InternalError : |
592 | // An unexpected internal error DPDisabled : Download protection is |
593 | // disabled |
594 | using Reason = mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_REASON; |
595 | |
596 | class PendingDBLookup; |
597 | |
598 | // A single use class private to ApplicationReputationService encapsulating an |
599 | // nsIApplicationReputationQuery and an nsIApplicationReputationCallback. Once |
600 | // created by ApplicationReputationService, it is guaranteed to call mCallback. |
601 | // This class is private to ApplicationReputationService. |
602 | class PendingLookup final : public nsIStreamListener, |
603 | public nsITimerCallback, |
604 | public nsINamed, |
605 | public nsIObserver, |
606 | public nsSupportsWeakReference { |
607 | public: |
608 | NS_DECL_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID , void** aInstancePtr) override; virtual MozExternalRefCountType AddRef(void) override; virtual MozExternalRefCountType Release (void) override; using HasThreadSafeRefCnt = std::false_type; protected: nsAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread ; public: |
609 | NS_DECL_NSIREQUESTOBSERVERvirtual nsresult OnStartRequest(nsIRequest *aRequest) override ; virtual nsresult OnStopRequest(nsIRequest *aRequest, nsresult aStatusCode) override; |
610 | NS_DECL_NSISTREAMLISTENERvirtual nsresult OnDataAvailable(nsIRequest *aRequest, nsIInputStream *aInputStream, uint64_t aOffset, uint32_t aCount) override; |
611 | NS_DECL_NSITIMERCALLBACKvirtual nsresult Notify(nsITimer *timer) override; inline void _ensure_GetName_exists(void) { static_assert(std::is_convertible <decltype(this), nsINamed*>::value, "nsITimerCallback implementations must also implement nsINamed" ); } |
612 | NS_DECL_NSINAMEDvirtual nsresult GetName(nsACString& aName) override; |
613 | NS_DECL_NSIOBSERVERvirtual nsresult Observe(nsISupports *aSubject, const char * aTopic , const char16_t * aData) override; |
614 | |
615 | // Constructor and destructor. |
616 | PendingLookup(nsIApplicationReputationQuery* aQuery, |
617 | nsIApplicationReputationCallback* aCallback); |
618 | |
619 | // Start the lookup. The lookup may have 2 parts: local and remote. In the |
620 | // local lookup, PendingDBLookups are created to query the local allow and |
621 | // blocklists for various URIs associated with this downloaded file. In the |
622 | // event that no results are found, a remote lookup is sent to the Application |
623 | // Reputation server. |
624 | nsresult StartLookup(); |
625 | |
626 | private: |
627 | ~PendingLookup(); |
628 | |
629 | friend class PendingDBLookup; |
630 | |
631 | // Telemetry states. |
632 | // Status of the remote response (valid or not). |
633 | enum SERVER_RESPONSE_TYPES { |
634 | SERVER_RESPONSE_VALID = 0, |
635 | SERVER_RESPONSE_FAILED = 1, |
636 | SERVER_RESPONSE_INVALID = 2, |
637 | }; |
638 | |
639 | // The target filename for the downloaded file. |
640 | nsCString mFileName; |
641 | |
642 | // True if extension of this file matches any extension in the |
643 | // kBinaryFileExtensions or sExecutableExts list. |
644 | bool mIsBinaryFile; |
645 | |
646 | // Number of blocklist and allowlist hits we have seen. |
647 | uint32_t mBlocklistCount; |
648 | uint32_t mAllowlistCount; |
649 | |
650 | // The query containing metadata about the downloaded file. |
651 | nsCOMPtr<nsIApplicationReputationQuery> mQuery; |
652 | |
653 | // The callback with which to report the verdict. |
654 | nsCOMPtr<nsIApplicationReputationCallback> mCallback; |
655 | |
656 | // An array of strings created from certificate information used to whitelist |
657 | // the downloaded file. |
658 | nsTArray<nsCString> mAllowlistSpecs; |
659 | // The source URI of the download (i.e. final URI after any redirects). |
660 | nsTArray<nsCString> mAnylistSpecs; |
661 | // The referrer and possibly any redirects. |
662 | nsTArray<nsCString> mBlocklistSpecs; |
663 | |
664 | // When we started this query |
665 | TimeStamp mStartTime; |
666 | |
667 | // The channel used to talk to the remote lookup server |
668 | nsCOMPtr<nsIChannel> mChannel; |
669 | |
670 | // Timer to abort this lookup if it takes too long |
671 | nsCOMPtr<nsITimer> mTimeoutTimer; |
672 | |
673 | // A protocol buffer for storing things we need in the remote request. We |
674 | // store the resource chain (redirect information) as well as signature |
675 | // information extracted using the Windows Authenticode API, if the binary is |
676 | // signed. |
677 | ClientDownloadRequest mRequest; |
678 | |
679 | // The response from the application reputation query. This is read in chunks |
680 | // as part of our nsIStreamListener implementation and may contain embedded |
681 | // NULLs. |
682 | nsCString mResponse; |
683 | |
684 | // The clock records the start time of a remote lookup request, used by |
685 | // telemetry. |
686 | PRIntervalTime mTelemetryRemoteRequestStartMs; |
687 | |
688 | // Returns the type of download binary for the file. |
689 | ClientDownloadRequest::DownloadType GetDownloadType( |
690 | const nsACString& aFilename); |
691 | |
692 | // Clean up and call the callback. PendingLookup must not be used after this |
693 | // function is called. |
694 | nsresult OnComplete(uint32_t aVerdict, Reason aReason, nsresult aRv); |
695 | |
696 | // Wrapper function for nsIStreamListener.onStopRequest to make it easy to |
697 | // guarantee calling the callback |
698 | nsresult OnStopRequestInternal(nsIRequest* aRequest, nsresult aResult, |
699 | uint32_t& aVerdict, Reason& aReason); |
700 | |
701 | // Return the hex-encoded hash of the whole URI. |
702 | nsresult GetSpecHash(nsACString& aSpec, nsACString& hexEncodedHash); |
703 | |
704 | // Strip url parameters, fragments, and user@pass fields from the URI spec |
705 | // using nsIURL. Hash data URIs and return blob URIs unfiltered. |
706 | nsresult GetStrippedSpec(nsIURI* aUri, nsACString& spec); |
707 | |
708 | // Escape '/' and '%' in certificate attribute values. |
709 | nsCString EscapeCertificateAttribute(const nsACString& aAttribute); |
710 | |
711 | // Escape ':' in fingerprint values. |
712 | nsCString EscapeFingerprint(const nsACString& aAttribute); |
713 | |
714 | // Generate whitelist strings for the given certificate pair from the same |
715 | // certificate chain. |
716 | nsresult GenerateWhitelistStringsForPair(nsIX509Cert* certificate, |
717 | nsIX509Cert* issuer); |
718 | |
719 | // Generate whitelist strings for the given certificate chain, which starts |
720 | // with the signer and may go all the way to the root cert. |
721 | nsresult GenerateWhitelistStringsForChain( |
722 | const ClientDownloadRequest_CertificateChain& aChain); |
723 | |
724 | // For signed binaries, generate strings of the form: |
725 | // http://sb-ssl.google.com/safebrowsing/csd/certificate/ |
726 | // <issuer_cert_sha1_fingerprint>[/CN=<cn>][/O=<org>][/OU=<unit>] |
727 | // for each (cert, issuer) pair in each chain of certificates that is |
728 | // associated with the binary. |
729 | nsresult GenerateWhitelistStrings(); |
730 | |
731 | // Parse the XPCOM certificate lists and stick them into the protocol buffer |
732 | // version. |
733 | nsresult ParseCertificates( |
734 | const nsTArray<nsTArray<nsTArray<uint8_t>>>& aSigArray); |
735 | |
736 | // Adds the redirects to mBlocklistSpecs to be looked up. |
737 | nsresult AddRedirects(nsIArray* aRedirects); |
738 | |
739 | // Helper function to ensure that we call PendingLookup::LookupNext or |
740 | // PendingLookup::OnComplete. |
741 | nsresult DoLookupInternal(); |
742 | |
743 | // Looks up all the URIs that may be responsible for allowlisting or |
744 | // blocklisting the downloaded file. These URIs may include whitelist strings |
745 | // generated by certificates verifying the binary as well as the target URI |
746 | // from which the file was downloaded. |
747 | nsresult LookupNext(); |
748 | |
749 | // Sends a query to the remote application reputation service. Returns NS_OK |
750 | // on success. |
751 | nsresult SendRemoteQuery(); |
752 | |
753 | // Helper function to ensure that we always call the callback. |
754 | nsresult SendRemoteQueryInternal(Reason& aReason); |
755 | }; |
756 | |
757 | // A single-use class for looking up a single URI in the safebrowsing DB. This |
758 | // class is private to PendingLookup. |
759 | class PendingDBLookup final : public nsIUrlClassifierCallback { |
760 | public: |
761 | NS_DECL_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID , void** aInstancePtr) override; virtual MozExternalRefCountType AddRef(void) override; virtual MozExternalRefCountType Release (void) override; using HasThreadSafeRefCnt = std::false_type; protected: nsAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread ; public: |
762 | NS_DECL_NSIURLCLASSIFIERCALLBACKvirtual nsresult HandleEvent(const nsACString& value) override ; |
763 | |
764 | // Constructor and destructor |
765 | explicit PendingDBLookup(PendingLookup* aPendingLookup); |
766 | |
767 | // Look up the given URI in the safebrowsing DBs, optionally on both the allow |
768 | // list and the blocklist. If there is a match, call |
769 | // PendingLookup::OnComplete. Otherwise, call PendingLookup::LookupNext. |
770 | nsresult LookupSpec(const nsACString& aSpec, const LookupType& aLookupType); |
771 | |
772 | private: |
773 | ~PendingDBLookup(); |
774 | |
775 | // The download appeared on the allowlist, blocklist, or no list (and thus |
776 | // could trigger a remote query. |
777 | enum LIST_TYPES { |
778 | ALLOW_LIST = 0, |
779 | BLOCK_LIST = 1, |
780 | NO_LIST = 2, |
781 | }; |
782 | |
783 | nsCString mSpec; |
784 | LookupType mLookupType; |
785 | RefPtr<PendingLookup> mPendingLookup; |
786 | nsresult LookupSpecInternal(const nsACString& aSpec); |
787 | }; |
788 | |
789 | NS_IMPL_ISUPPORTS(PendingDBLookup, nsIUrlClassifierCallback)MozExternalRefCountType PendingDBLookup::AddRef(void) { static_assert (!std::is_destructible_v<PendingDBLookup>, "Reference-counted class " "PendingDBLookup" " should not have a public destructor. " "Make this class's destructor non-public" ); do { static_assert( mozilla::detail::AssertionConditionType <decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0" " (" "illegal refcnt" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 789); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0" ") (" "illegal refcnt" ")"); do { *((volatile int*)__null) = 789; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("PendingDBLookup" != nullptr)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!("PendingDBLookup" != nullptr ))), 0))) { do { } while (false); MOZ_ReportAssertionFailure( "\"PendingDBLookup\" != nullptr" " (" "Must specify a name" ")" , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 789); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingDBLookup\" != nullptr" ") (" "Must specify a name" ")"); do { *((volatile int*)__null ) = 789; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread .AssertOwnership("PendingDBLookup" " not thread-safe"); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), ("PendingDBLookup" ), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType PendingDBLookup::Release(void) { do { static_assert( mozilla ::detail::AssertionConditionType<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(int32_t(mRefCnt) > 0))), 0))) { do { } while (false ); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 789); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release" ")"); do { *((volatile int*)__null) = 789 ; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("PendingDBLookup" != nullptr)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!("PendingDBLookup" != nullptr ))), 0))) { do { } while (false); MOZ_ReportAssertionFailure( "\"PendingDBLookup\" != nullptr" " (" "Must specify a name" ")" , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 789); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingDBLookup\" != nullptr" ") (" "Must specify a name" ")"); do { *((volatile int*)__null ) = 789; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread .AssertOwnership("PendingDBLookup" " not thread-safe"); const char* const nametmp = "PendingDBLookup"; nsrefcnt count = -- mRefCnt; NS_LogRelease((this), (count), (nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return 0; } return count ; } nsresult PendingDBLookup::QueryInterface(const nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak (NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!" , "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 789); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE ; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE" ); static const QITableEntry table[] = { {&mozilla::detail ::kImplementedIID<PendingDBLookup, nsIUrlClassifierCallback >, int32_t( reinterpret_cast<char*>(static_cast<nsIUrlClassifierCallback *>((PendingDBLookup*)0x1000)) - reinterpret_cast<char*> ((PendingDBLookup*)0x1000))}, {&mozilla::detail::kImplementedIID <PendingDBLookup, nsISupports>, int32_t(reinterpret_cast <char*>(static_cast<nsISupports*>( static_cast< nsIUrlClassifierCallback*>((PendingDBLookup*)0x1000))) - reinterpret_cast <char*>((PendingDBLookup*)0x1000))}, { nullptr, 0 } } ; static_assert((sizeof(table) / sizeof(table[0])) > 1, "need at least 1 interface" ); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID , aInstancePtr, table); return rv; } |
790 | |
791 | PendingDBLookup::PendingDBLookup(PendingLookup* aPendingLookup) |
792 | : mLookupType(LookupType::BothLists), mPendingLookup(aPendingLookup) { |
793 | LOG(("Created pending DB lookup [this = %p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Created pending DB lookup [this = %p]" , this); } } while (0); |
794 | } |
795 | |
796 | PendingDBLookup::~PendingDBLookup() { |
797 | LOG(("Destroying pending DB lookup [this = %p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Destroying pending DB lookup [this = %p]" , this); } } while (0); |
798 | mPendingLookup = nullptr; |
799 | } |
800 | |
801 | nsresult PendingDBLookup::LookupSpec(const nsACString& aSpec, |
802 | const LookupType& aLookupType) { |
803 | LOG(("Checking principal %s [this=%p]", aSpec.Data(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Checking principal %s [this=%p]" , aSpec.Data(), this); } } while (0); |
804 | mSpec = aSpec; |
805 | mLookupType = aLookupType; |
806 | nsresult rv = LookupSpecInternal(aSpec); |
807 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
808 | nsAutoCString errorName; |
809 | mozilla::GetErrorName(rv, errorName); |
810 | LOG(("Error in LookupSpecInternal() [rv = %s, this = %p]", errorName.get(),do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Error in LookupSpecInternal() [rv = %s, this = %p]" , errorName.get(), this); } } while (0) |
811 | this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Error in LookupSpecInternal() [rv = %s, this = %p]" , errorName.get(), this); } } while (0); |
812 | return mPendingLookup->LookupNext(); // ignore this lookup and move to next |
813 | } |
814 | // LookupSpecInternal has called nsIUrlClassifierCallback.lookup, which is |
815 | // guaranteed to call HandleEvent. |
816 | return rv; |
817 | } |
818 | |
819 | nsresult PendingDBLookup::LookupSpecInternal(const nsACString& aSpec) { |
820 | nsresult rv; |
821 | |
822 | nsCOMPtr<nsIURI> uri; |
823 | nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID"@mozilla.org/network/io-service;1", &rv); |
824 | rv = ios->NewURI(aSpec, nullptr, nullptr, getter_AddRefs(uri)); |
825 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 825); return rv; } } while (false); |
826 | |
827 | OriginAttributes attrs; |
828 | nsCOMPtr<nsIPrincipal> principal = |
829 | BasePrincipal::CreateContentPrincipal(uri, attrs); |
830 | if (!principal) { |
831 | return NS_ERROR_FAILURE; |
832 | } |
833 | |
834 | // Check local lists to see if the URI has already been whitelisted or |
835 | // blacklisted. |
836 | LOG(("Checking DB service for principal %s [this = %p]", mSpec.get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Checking DB service for principal %s [this = %p]" , mSpec.get(), this); } } while (0); |
837 | nsCOMPtr<nsIUrlClassifierDBService> dbService = |
838 | mozilla::components::UrlClassifierDB::Service(&rv); |
839 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 839); return rv; } } while (false); |
840 | |
841 | nsAutoCString tables; |
842 | nsAutoCString allowlist; |
843 | Preferences::GetCString(PREF_DOWNLOAD_ALLOW_TABLE"urlclassifier.downloadAllowTable", allowlist); |
844 | if ((mLookupType != LookupType::BlocklistOnly) && !allowlist.IsEmpty()) { |
845 | tables.Append(allowlist); |
846 | } |
847 | nsAutoCString blocklist; |
848 | Preferences::GetCString(PREF_DOWNLOAD_BLOCK_TABLE"urlclassifier.downloadBlockTable", blocklist); |
849 | if ((mLookupType != LookupType::AllowlistOnly) && !blocklist.IsEmpty()) { |
850 | if (!tables.IsEmpty()) { |
851 | tables.Append(','); |
852 | } |
853 | tables.Append(blocklist); |
854 | } |
855 | return dbService->Lookup(principal, tables, this); |
856 | } |
857 | |
858 | NS_IMETHODIMPnsresult |
859 | PendingDBLookup::HandleEvent(const nsACString& tables) { |
860 | // HandleEvent is guaranteed to call either: |
861 | // 1) PendingLookup::OnComplete if the URL matches the blocklist, or |
862 | // 2) PendingLookup::LookupNext if the URL does not match the blocklist. |
863 | // Blocklisting trumps allowlisting. |
864 | nsAutoCString blockList; |
865 | Preferences::GetCString(PREF_DOWNLOAD_BLOCK_TABLE"urlclassifier.downloadBlockTable", blockList); |
866 | if ((mLookupType != LookupType::AllowlistOnly) && |
867 | FindInReadable(blockList, tables)) { |
868 | mPendingLookup->mBlocklistCount++; |
869 | Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_LOCAL, BLOCK_LIST); |
870 | LOG(("Found principal %s on blocklist [this = %p]", mSpec.get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Found principal %s on blocklist [this = %p]" , mSpec.get(), this); } } while (0); |
871 | return mPendingLookup->OnComplete( |
872 | nsIApplicationReputationService::VERDICT_DANGEROUS, |
873 | Reason::LocalBlocklist, NS_OK); |
874 | } |
875 | |
876 | nsAutoCString allowList; |
877 | Preferences::GetCString(PREF_DOWNLOAD_ALLOW_TABLE"urlclassifier.downloadAllowTable", allowList); |
878 | if ((mLookupType != LookupType::BlocklistOnly) && |
879 | FindInReadable(allowList, tables)) { |
880 | mPendingLookup->mAllowlistCount++; |
881 | Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_LOCAL, ALLOW_LIST); |
882 | LOG(("Found principal %s on allowlist [this = %p]", mSpec.get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Found principal %s on allowlist [this = %p]" , mSpec.get(), this); } } while (0); |
883 | // Don't call onComplete, since blocklisting trumps allowlisting |
884 | return mPendingLookup->LookupNext(); |
885 | } |
886 | |
887 | LOG(("Didn't find principal %s on any list [this = %p]", mSpec.get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Didn't find principal %s on any list [this = %p]" , mSpec.get(), this); } } while (0); |
888 | Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_LOCAL, NO_LIST); |
889 | return mPendingLookup->LookupNext(); |
890 | } |
891 | |
892 | NS_IMPL_ISUPPORTS(PendingLookup, nsIStreamListener, nsIRequestObserver,MozExternalRefCountType PendingLookup::AddRef(void) { static_assert (!std::is_destructible_v<PendingLookup>, "Reference-counted class " "PendingLookup" " should not have a public destructor. " "Make this class's destructor non-public" ); do { static_assert( mozilla::detail::AssertionConditionType <decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0" " (" "illegal refcnt" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 894); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0" ") (" "illegal refcnt" ")"); do { *((volatile int*)__null) = 894; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("PendingLookup" != nullptr)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!("PendingLookup" != nullptr)) ), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"PendingLookup\" != nullptr" " (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 894); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr" ") (" "Must specify a name" ")"); do { *((volatile int*)__null ) = 894; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread .AssertOwnership("PendingLookup" " not thread-safe"); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), ("PendingLookup" ), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType PendingLookup::Release(void) { do { static_assert( mozilla:: detail::AssertionConditionType<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(int32_t(mRefCnt) > 0))), 0))) { do { } while (false ); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 894); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release" ")"); do { *((volatile int*)__null) = 894 ; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("PendingLookup" != nullptr)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!("PendingLookup" != nullptr)) ), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"PendingLookup\" != nullptr" " (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 894); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr" ") (" "Must specify a name" ")"); do { *((volatile int*)__null ) = 894; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread .AssertOwnership("PendingLookup" " not thread-safe"); const char * const nametmp = "PendingLookup"; nsrefcnt count = --mRefCnt ; NS_LogRelease((this), (count), (nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return 0; } return count; } nsresult PendingLookup::QueryInterface(const nsIID& aIID, void** aInstancePtr ) { do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION , "QueryInterface requires a non-NULL destination!", "aInstancePtr" , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 894); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE ; static_assert(6 > 0, "Need more arguments to NS_INTERFACE_TABLE" ); static const QITableEntry table[] = { {&mozilla::detail ::kImplementedIID<PendingLookup, nsIStreamListener>, int32_t ( reinterpret_cast<char*>(static_cast<nsIStreamListener *>((PendingLookup*)0x1000)) - reinterpret_cast<char*> ((PendingLookup*)0x1000))}, {&mozilla::detail::kImplementedIID <PendingLookup, nsIRequestObserver>, int32_t( reinterpret_cast <char*>(static_cast<nsIRequestObserver*>((PendingLookup *)0x1000)) - reinterpret_cast<char*>((PendingLookup*)0x1000 ))}, {&mozilla::detail::kImplementedIID<PendingLookup, nsIObserver>, int32_t( reinterpret_cast<char*>(static_cast <nsIObserver*>((PendingLookup*)0x1000)) - reinterpret_cast <char*>((PendingLookup*)0x1000))}, {&mozilla::detail ::kImplementedIID<PendingLookup, nsISupportsWeakReference> , int32_t( reinterpret_cast<char*>(static_cast<nsISupportsWeakReference *>((PendingLookup*)0x1000)) - reinterpret_cast<char*> ((PendingLookup*)0x1000))}, {&mozilla::detail::kImplementedIID <PendingLookup, nsITimerCallback>, int32_t( reinterpret_cast <char*>(static_cast<nsITimerCallback*>((PendingLookup *)0x1000)) - reinterpret_cast<char*>((PendingLookup*)0x1000 ))}, {&mozilla::detail::kImplementedIID<PendingLookup, nsINamed>, int32_t( reinterpret_cast<char*>(static_cast <nsINamed*>((PendingLookup*)0x1000)) - reinterpret_cast <char*>((PendingLookup*)0x1000))}, {&mozilla::detail ::kImplementedIID<PendingLookup, nsISupports>, int32_t( reinterpret_cast<char*>(static_cast<nsISupports*> ( static_cast<nsIStreamListener*>((PendingLookup*)0x1000 ))) - reinterpret_cast<char*>((PendingLookup*)0x1000))} , { nullptr, 0 } } ; static_assert((sizeof(table) / sizeof(table [0])) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI (static_cast<void*>(this), aIID, aInstancePtr, table); return rv; } |
893 | nsIObserver, nsISupportsWeakReference, nsITimerCallback,MozExternalRefCountType PendingLookup::AddRef(void) { static_assert (!std::is_destructible_v<PendingLookup>, "Reference-counted class " "PendingLookup" " should not have a public destructor. " "Make this class's destructor non-public" ); do { static_assert( mozilla::detail::AssertionConditionType <decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0" " (" "illegal refcnt" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 894); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0" ") (" "illegal refcnt" ")"); do { *((volatile int*)__null) = 894; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("PendingLookup" != nullptr)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!("PendingLookup" != nullptr)) ), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"PendingLookup\" != nullptr" " (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 894); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr" ") (" "Must specify a name" ")"); do { *((volatile int*)__null ) = 894; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread .AssertOwnership("PendingLookup" " not thread-safe"); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), ("PendingLookup" ), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType PendingLookup::Release(void) { do { static_assert( mozilla:: detail::AssertionConditionType<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(int32_t(mRefCnt) > 0))), 0))) { do { } while (false ); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 894); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release" ")"); do { *((volatile int*)__null) = 894 ; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("PendingLookup" != nullptr)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!("PendingLookup" != nullptr)) ), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"PendingLookup\" != nullptr" " (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 894); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr" ") (" "Must specify a name" ")"); do { *((volatile int*)__null ) = 894; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread .AssertOwnership("PendingLookup" " not thread-safe"); const char * const nametmp = "PendingLookup"; nsrefcnt count = --mRefCnt ; NS_LogRelease((this), (count), (nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return 0; } return count; } nsresult PendingLookup::QueryInterface(const nsIID& aIID, void** aInstancePtr ) { do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION , "QueryInterface requires a non-NULL destination!", "aInstancePtr" , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 894); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE ; static_assert(6 > 0, "Need more arguments to NS_INTERFACE_TABLE" ); static const QITableEntry table[] = { {&mozilla::detail ::kImplementedIID<PendingLookup, nsIStreamListener>, int32_t ( reinterpret_cast<char*>(static_cast<nsIStreamListener *>((PendingLookup*)0x1000)) - reinterpret_cast<char*> ((PendingLookup*)0x1000))}, {&mozilla::detail::kImplementedIID <PendingLookup, nsIRequestObserver>, int32_t( reinterpret_cast <char*>(static_cast<nsIRequestObserver*>((PendingLookup *)0x1000)) - reinterpret_cast<char*>((PendingLookup*)0x1000 ))}, {&mozilla::detail::kImplementedIID<PendingLookup, nsIObserver>, int32_t( reinterpret_cast<char*>(static_cast <nsIObserver*>((PendingLookup*)0x1000)) - reinterpret_cast <char*>((PendingLookup*)0x1000))}, {&mozilla::detail ::kImplementedIID<PendingLookup, nsISupportsWeakReference> , int32_t( reinterpret_cast<char*>(static_cast<nsISupportsWeakReference *>((PendingLookup*)0x1000)) - reinterpret_cast<char*> ((PendingLookup*)0x1000))}, {&mozilla::detail::kImplementedIID <PendingLookup, nsITimerCallback>, int32_t( reinterpret_cast <char*>(static_cast<nsITimerCallback*>((PendingLookup *)0x1000)) - reinterpret_cast<char*>((PendingLookup*)0x1000 ))}, {&mozilla::detail::kImplementedIID<PendingLookup, nsINamed>, int32_t( reinterpret_cast<char*>(static_cast <nsINamed*>((PendingLookup*)0x1000)) - reinterpret_cast <char*>((PendingLookup*)0x1000))}, {&mozilla::detail ::kImplementedIID<PendingLookup, nsISupports>, int32_t( reinterpret_cast<char*>(static_cast<nsISupports*> ( static_cast<nsIStreamListener*>((PendingLookup*)0x1000 ))) - reinterpret_cast<char*>((PendingLookup*)0x1000))} , { nullptr, 0 } } ; static_assert((sizeof(table) / sizeof(table [0])) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI (static_cast<void*>(this), aIID, aInstancePtr, table); return rv; } |
894 | nsINamed)MozExternalRefCountType PendingLookup::AddRef(void) { static_assert (!std::is_destructible_v<PendingLookup>, "Reference-counted class " "PendingLookup" " should not have a public destructor. " "Make this class's destructor non-public" ); do { static_assert( mozilla::detail::AssertionConditionType <decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0" " (" "illegal refcnt" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 894); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0" ") (" "illegal refcnt" ")"); do { *((volatile int*)__null) = 894; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("PendingLookup" != nullptr)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!("PendingLookup" != nullptr)) ), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"PendingLookup\" != nullptr" " (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 894); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr" ") (" "Must specify a name" ")"); do { *((volatile int*)__null ) = 894; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread .AssertOwnership("PendingLookup" " not thread-safe"); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), ("PendingLookup" ), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType PendingLookup::Release(void) { do { static_assert( mozilla:: detail::AssertionConditionType<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(int32_t(mRefCnt) > 0))), 0))) { do { } while (false ); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 894); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release" ")"); do { *((volatile int*)__null) = 894 ; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("PendingLookup" != nullptr)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!("PendingLookup" != nullptr)) ), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"PendingLookup\" != nullptr" " (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 894); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr" ") (" "Must specify a name" ")"); do { *((volatile int*)__null ) = 894; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread .AssertOwnership("PendingLookup" " not thread-safe"); const char * const nametmp = "PendingLookup"; nsrefcnt count = --mRefCnt ; NS_LogRelease((this), (count), (nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return 0; } return count; } nsresult PendingLookup::QueryInterface(const nsIID& aIID, void** aInstancePtr ) { do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION , "QueryInterface requires a non-NULL destination!", "aInstancePtr" , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 894); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE ; static_assert(6 > 0, "Need more arguments to NS_INTERFACE_TABLE" ); static const QITableEntry table[] = { {&mozilla::detail ::kImplementedIID<PendingLookup, nsIStreamListener>, int32_t ( reinterpret_cast<char*>(static_cast<nsIStreamListener *>((PendingLookup*)0x1000)) - reinterpret_cast<char*> ((PendingLookup*)0x1000))}, {&mozilla::detail::kImplementedIID <PendingLookup, nsIRequestObserver>, int32_t( reinterpret_cast <char*>(static_cast<nsIRequestObserver*>((PendingLookup *)0x1000)) - reinterpret_cast<char*>((PendingLookup*)0x1000 ))}, {&mozilla::detail::kImplementedIID<PendingLookup, nsIObserver>, int32_t( reinterpret_cast<char*>(static_cast <nsIObserver*>((PendingLookup*)0x1000)) - reinterpret_cast <char*>((PendingLookup*)0x1000))}, {&mozilla::detail ::kImplementedIID<PendingLookup, nsISupportsWeakReference> , int32_t( reinterpret_cast<char*>(static_cast<nsISupportsWeakReference *>((PendingLookup*)0x1000)) - reinterpret_cast<char*> ((PendingLookup*)0x1000))}, {&mozilla::detail::kImplementedIID <PendingLookup, nsITimerCallback>, int32_t( reinterpret_cast <char*>(static_cast<nsITimerCallback*>((PendingLookup *)0x1000)) - reinterpret_cast<char*>((PendingLookup*)0x1000 ))}, {&mozilla::detail::kImplementedIID<PendingLookup, nsINamed>, int32_t( reinterpret_cast<char*>(static_cast <nsINamed*>((PendingLookup*)0x1000)) - reinterpret_cast <char*>((PendingLookup*)0x1000))}, {&mozilla::detail ::kImplementedIID<PendingLookup, nsISupports>, int32_t( reinterpret_cast<char*>(static_cast<nsISupports*> ( static_cast<nsIStreamListener*>((PendingLookup*)0x1000 ))) - reinterpret_cast<char*>((PendingLookup*)0x1000))} , { nullptr, 0 } } ; static_assert((sizeof(table) / sizeof(table [0])) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI (static_cast<void*>(this), aIID, aInstancePtr, table); return rv; } |
895 | |
896 | PendingLookup::PendingLookup(nsIApplicationReputationQuery* aQuery, |
897 | nsIApplicationReputationCallback* aCallback) |
898 | : mIsBinaryFile(false), |
899 | mBlocklistCount(0), |
900 | mAllowlistCount(0), |
901 | mQuery(aQuery), |
902 | mCallback(aCallback) { |
903 | LOG(("Created pending lookup [this = %p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Created pending lookup [this = %p]" , this); } } while (0); |
904 | } |
905 | |
906 | PendingLookup::~PendingLookup() { |
907 | LOG(("Destroying pending lookup [this = %p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Destroying pending lookup [this = %p]" , this); } } while (0); |
908 | } |
909 | |
910 | static const char* const kDmgFileExtensions[] = { |
911 | ".cdr", ".dart", ".dc42", ".diskcopy42", |
912 | ".dmg", ".dmgpart", ".dvdr", ".img", |
913 | ".imgpart", ".iso", ".ndif", ".smi", |
914 | ".sparsebundle", ".sparseimage", ".toast", ".udif", |
915 | }; |
916 | |
917 | static const char* const kRarFileExtensions[] = { |
918 | ".r00", ".r01", ".r02", ".r03", ".r04", ".r05", ".r06", ".r07", |
919 | ".r08", ".r09", ".r10", ".r11", ".r12", ".r13", ".r14", ".r15", |
920 | ".r16", ".r17", ".r18", ".r19", ".r20", ".r21", ".r22", ".r23", |
921 | ".r24", ".r25", ".r26", ".r27", ".r28", ".r29", ".rar", |
922 | }; |
923 | |
924 | static const char* const kZipFileExtensions[] = { |
925 | ".zip", // Generic archive |
926 | ".zipx", // WinZip |
927 | }; |
928 | |
929 | static const char* GetFileExt(const nsACString& aFilename, |
930 | const char* const aFileExtensions[], |
931 | const size_t aLength) { |
932 | for (size_t i = 0; i < aLength; ++i) { |
933 | if (StringEndsWith(aFilename, nsDependentCString(aFileExtensions[i]))) { |
934 | return aFileExtensions[i]; |
935 | } |
936 | } |
937 | return nullptr; |
938 | } |
939 | |
940 | static const char* GetFileExt(const nsACString& aFilename) { |
941 | #define _GetFileExt(_f, _l)GetFileExt(_f, _l, ArrayLength(_l)) GetFileExt(_f, _l, ArrayLength(_l)) |
942 | const char* ext = _GetFileExt(GetFileExt(aFilename, ApplicationReputationService::kBinaryFileExtensions , ArrayLength(ApplicationReputationService::kBinaryFileExtensions )) |
943 | aFilename, ApplicationReputationService::kBinaryFileExtensions)GetFileExt(aFilename, ApplicationReputationService::kBinaryFileExtensions , ArrayLength(ApplicationReputationService::kBinaryFileExtensions )); |
944 | if (ext == nullptr && |
945 | !_GetFileExt(aFilename,GetFileExt(aFilename, ApplicationReputationService::kNonBinaryExecutables , ArrayLength(ApplicationReputationService::kNonBinaryExecutables )) |
946 | ApplicationReputationService::kNonBinaryExecutables)GetFileExt(aFilename, ApplicationReputationService::kNonBinaryExecutables , ArrayLength(ApplicationReputationService::kNonBinaryExecutables ))) { |
947 | ext = _GetFileExt(aFilename, sExecutableExts)GetFileExt(aFilename, sExecutableExts, ArrayLength(sExecutableExts )); |
948 | } |
949 | return ext; |
950 | } |
951 | |
952 | // Returns true if the file extension matches one in the given array. |
953 | static bool IsFileType(const nsACString& aFilename, |
954 | const char* const aFileExtensions[], |
955 | const size_t aLength) { |
956 | return GetFileExt(aFilename, aFileExtensions, aLength) != nullptr; |
957 | } |
958 | |
959 | static bool IsBinary(const nsACString& aFilename) { |
960 | return IsFileType(aFilename, |
961 | ApplicationReputationService::kBinaryFileExtensions, |
962 | ArrayLength( |
963 | ApplicationReputationService::kBinaryFileExtensions)) || |
964 | (!IsFileType( |
965 | aFilename, ApplicationReputationService::kNonBinaryExecutables, |
966 | ArrayLength( |
967 | ApplicationReputationService::kNonBinaryExecutables)) && |
968 | IsFileType(aFilename, sExecutableExts, ArrayLength(sExecutableExts))); |
969 | } |
970 | |
971 | ClientDownloadRequest::DownloadType PendingLookup::GetDownloadType( |
972 | const nsACString& aFilename) { |
973 | MOZ_ASSERT(IsBinary(aFilename))do { static_assert( mozilla::detail::AssertionConditionType< decltype(IsBinary(aFilename))>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(IsBinary(aFilename)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsBinary(aFilename)" , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 973); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsBinary(aFilename)" ")"); do { *((volatile int*)__null) = 973; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
974 | |
975 | // From |
976 | // https://cs.chromium.org/chromium/src/chrome/common/safe_browsing/download_protection_util.cc?l=17 |
977 | if (StringEndsWith(aFilename, ".zip"_ns)) { |
978 | return ClientDownloadRequest::ZIPPED_EXECUTABLE; |
979 | } else if (StringEndsWith(aFilename, ".apk"_ns)) { |
980 | return ClientDownloadRequest::ANDROID_APK; |
981 | } else if (StringEndsWith(aFilename, ".app"_ns) || |
982 | StringEndsWith(aFilename, ".applescript"_ns) || |
983 | StringEndsWith(aFilename, ".cdr"_ns) || |
984 | StringEndsWith(aFilename, ".dart"_ns) || |
985 | StringEndsWith(aFilename, ".dc42"_ns) || |
986 | StringEndsWith(aFilename, ".diskcopy42"_ns) || |
987 | StringEndsWith(aFilename, ".dmg"_ns) || |
988 | StringEndsWith(aFilename, ".dmgpart"_ns) || |
989 | StringEndsWith(aFilename, ".dvdr"_ns) || |
990 | StringEndsWith(aFilename, ".img"_ns) || |
991 | StringEndsWith(aFilename, ".imgpart"_ns) || |
992 | StringEndsWith(aFilename, ".iso"_ns) || |
993 | StringEndsWith(aFilename, ".mpkg"_ns) || |
994 | StringEndsWith(aFilename, ".ndif"_ns) || |
995 | StringEndsWith(aFilename, ".osas"_ns) || |
996 | StringEndsWith(aFilename, ".osax"_ns) || |
997 | StringEndsWith(aFilename, ".pkg"_ns) || |
998 | StringEndsWith(aFilename, ".scpt"_ns) || |
999 | StringEndsWith(aFilename, ".scptd"_ns) || |
1000 | StringEndsWith(aFilename, ".seplugin"_ns) || |
1001 | StringEndsWith(aFilename, ".smi"_ns) || |
1002 | StringEndsWith(aFilename, ".sparsebundle"_ns) || |
1003 | StringEndsWith(aFilename, ".sparseimage"_ns) || |
1004 | StringEndsWith(aFilename, ".toast"_ns) || |
1005 | StringEndsWith(aFilename, ".udif"_ns)) { |
1006 | return ClientDownloadRequest::MAC_EXECUTABLE; |
1007 | } |
1008 | |
1009 | return ClientDownloadRequest::WIN_EXECUTABLE; // default to Windows binaries |
1010 | } |
1011 | |
1012 | nsresult PendingLookup::LookupNext() { |
1013 | // We must call LookupNext or SendRemoteQuery upon return. |
1014 | // Look up all of the URLs that could allow or block this download. |
1015 | // Blocklist first. |
1016 | |
1017 | // If a url is in blocklist we should call PendingLookup::OnComplete directly. |
1018 | MOZ_ASSERT(mBlocklistCount == 0)do { static_assert( mozilla::detail::AssertionConditionType< decltype(mBlocklistCount == 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(mBlocklistCount == 0))), 0)) ) { do { } while (false); MOZ_ReportAssertionFailure("mBlocklistCount == 0" , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1018); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mBlocklistCount == 0" ")"); do { *((volatile int*)__null) = 1018; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
1019 | |
1020 | nsCString spec; |
1021 | if (!mAnylistSpecs.IsEmpty()) { |
1022 | // Check the source URI only. |
1023 | spec = mAnylistSpecs.PopLastElement(); |
1024 | RefPtr<PendingDBLookup> lookup(new PendingDBLookup(this)); |
1025 | |
1026 | // We don't need to check whitelist if the file is not a binary file. |
1027 | auto type = |
1028 | mIsBinaryFile ? LookupType::BothLists : LookupType::BlocklistOnly; |
1029 | return lookup->LookupSpec(spec, type); |
1030 | } |
1031 | |
1032 | if (!mBlocklistSpecs.IsEmpty()) { |
1033 | // Check the referrer and redirect chain. |
1034 | spec = mBlocklistSpecs.PopLastElement(); |
1035 | RefPtr<PendingDBLookup> lookup(new PendingDBLookup(this)); |
1036 | return lookup->LookupSpec(spec, LookupType::BlocklistOnly); |
1037 | } |
1038 | |
1039 | // Now that we've looked up all of the URIs against the blocklist, |
1040 | // if any of mAnylistSpecs or mAllowlistSpecs matched the allowlist, |
1041 | // go ahead and pass. |
1042 | if (mAllowlistCount > 0) { |
1043 | return OnComplete(nsIApplicationReputationService::VERDICT_SAFE, |
1044 | Reason::LocalWhitelist, NS_OK); |
1045 | } |
1046 | |
1047 | MOZ_ASSERT_IF(!mIsBinaryFile, mAllowlistSpecs.Length() == 0)do { if (!mIsBinaryFile) { do { static_assert( mozilla::detail ::AssertionConditionType<decltype(mAllowlistSpecs.Length() == 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!(mAllowlistSpecs.Length() == 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("mAllowlistSpecs.Length() == 0" , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1047); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAllowlistSpecs.Length() == 0" ")"); do { *((volatile int*)__null) = 1047; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); } } while ( false); |
1048 | |
1049 | // Only binary signatures remain. |
1050 | if (!mAllowlistSpecs.IsEmpty()) { |
1051 | spec = mAllowlistSpecs.PopLastElement(); |
1052 | LOG(("PendingLookup::LookupNext: checking %s on allowlist", spec.get()))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::LookupNext: checking %s on allowlist" , spec.get()); } } while (0); |
1053 | RefPtr<PendingDBLookup> lookup(new PendingDBLookup(this)); |
1054 | return lookup->LookupSpec(spec, LookupType::AllowlistOnly); |
1055 | } |
1056 | |
1057 | if (!mFileName.IsEmpty()) { |
1058 | if (IsBinary(mFileName)) { |
1059 | AccumulateCategorical( |
1060 | mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_BINARY_TYPE:: |
1061 | BinaryFile); |
1062 | } else if (IsFileType(mFileName, kSafeFileExtensions, |
1063 | ArrayLength(kSafeFileExtensions))) { |
1064 | AccumulateCategorical( |
1065 | mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_BINARY_TYPE:: |
1066 | NonBinaryFile); |
1067 | } else if (IsFileType(mFileName, kMozNonBinaryExecutables, |
1068 | ArrayLength(kMozNonBinaryExecutables))) { |
1069 | AccumulateCategorical( |
1070 | mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_BINARY_TYPE:: |
1071 | MozNonBinaryFile); |
1072 | } else { |
1073 | AccumulateCategorical( |
1074 | mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_BINARY_TYPE:: |
1075 | UnknownFile); |
1076 | } |
1077 | } else { |
1078 | AccumulateCategorical( |
1079 | mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_BINARY_TYPE:: |
1080 | MissingFilename); |
1081 | } |
1082 | |
1083 | if (IsFileType(mFileName, kDmgFileExtensions, |
1084 | ArrayLength(kDmgFileExtensions))) { |
1085 | AccumulateCategorical( |
1086 | mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_BINARY_ARCHIVE:: |
1087 | DmgFile); |
1088 | } else if (IsFileType(mFileName, kRarFileExtensions, |
1089 | ArrayLength(kRarFileExtensions))) { |
1090 | AccumulateCategorical( |
1091 | mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_BINARY_ARCHIVE:: |
1092 | RarFile); |
1093 | } else if (IsFileType(mFileName, kZipFileExtensions, |
1094 | ArrayLength(kZipFileExtensions))) { |
1095 | AccumulateCategorical( |
1096 | mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_BINARY_ARCHIVE:: |
1097 | ZipFile); |
1098 | } else if (mIsBinaryFile) { |
1099 | AccumulateCategorical( |
1100 | mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_BINARY_ARCHIVE:: |
1101 | OtherBinaryFile); |
1102 | } |
1103 | |
1104 | // There are no more URIs to check against local list. If the file is |
1105 | // not eligible for remote lookup, bail. |
1106 | if (!mIsBinaryFile) { |
1107 | LOG(("Not eligible for remote lookups [this=%p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Not eligible for remote lookups [this=%p]" , this); } } while (0); |
1108 | return OnComplete(nsIApplicationReputationService::VERDICT_SAFE, |
1109 | Reason::NonBinaryFile, NS_OK); |
1110 | } |
1111 | |
1112 | nsresult rv = SendRemoteQuery(); |
1113 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
1114 | return OnComplete(nsIApplicationReputationService::VERDICT_SAFE, |
1115 | Reason::InternalError, rv); |
1116 | } |
1117 | return NS_OK; |
1118 | } |
1119 | |
1120 | nsCString PendingLookup::EscapeCertificateAttribute( |
1121 | const nsACString& aAttribute) { |
1122 | // Escape '/' because it's a field separator, and '%' because Chrome does |
1123 | nsCString escaped; |
1124 | escaped.SetCapacity(aAttribute.Length()); |
1125 | for (unsigned int i = 0; i < aAttribute.Length(); ++i) { |
1126 | if (aAttribute.Data()[i] == '%') { |
1127 | escaped.AppendLiteral("%25"); |
1128 | } else if (aAttribute.Data()[i] == '/') { |
1129 | escaped.AppendLiteral("%2F"); |
1130 | } else if (aAttribute.Data()[i] == ' ') { |
1131 | escaped.AppendLiteral("%20"); |
1132 | } else { |
1133 | escaped.Append(aAttribute.Data()[i]); |
1134 | } |
1135 | } |
1136 | return escaped; |
1137 | } |
1138 | |
1139 | nsCString PendingLookup::EscapeFingerprint(const nsACString& aFingerprint) { |
1140 | // Google's fingerprint doesn't have colons |
1141 | nsCString escaped; |
1142 | escaped.SetCapacity(aFingerprint.Length()); |
1143 | for (unsigned int i = 0; i < aFingerprint.Length(); ++i) { |
1144 | if (aFingerprint.Data()[i] != ':') { |
1145 | escaped.Append(aFingerprint.Data()[i]); |
1146 | } |
1147 | } |
1148 | return escaped; |
1149 | } |
1150 | |
1151 | nsresult PendingLookup::GenerateWhitelistStringsForPair( |
1152 | nsIX509Cert* certificate, nsIX509Cert* issuer) { |
1153 | // The whitelist paths have format: |
1154 | // http://sb-ssl.google.com/safebrowsing/csd/certificate/<issuer_cert_fingerprint>[/CN=<cn>][/O=<org>][/OU=<unit>] |
1155 | // Any of CN, O, or OU may be omitted from the whitelist entry. Unfortunately |
1156 | // this is not publicly documented, but the Chrome implementation can be found |
1157 | // here: |
1158 | // https://code.google.com/p/chromium/codesearch#search/&q=GetCertificateWhitelistStrings |
1159 | nsCString whitelistString( |
1160 | "http://sb-ssl.google.com/safebrowsing/csd/certificate/"); |
1161 | |
1162 | nsString fingerprint; |
1163 | nsresult rv = issuer->GetSha1Fingerprint(fingerprint); |
1164 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1164); return rv; } } while (false); |
1165 | whitelistString.Append(EscapeFingerprint(NS_ConvertUTF16toUTF8(fingerprint))); |
1166 | |
1167 | nsString commonName; |
1168 | rv = certificate->GetCommonName(commonName); |
1169 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1169); return rv; } } while (false); |
1170 | if (!commonName.IsEmpty()) { |
1171 | whitelistString.AppendLiteral("/CN="); |
1172 | whitelistString.Append( |
1173 | EscapeCertificateAttribute(NS_ConvertUTF16toUTF8(commonName))); |
1174 | } |
1175 | |
1176 | nsString organization; |
1177 | rv = certificate->GetOrganization(organization); |
1178 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1178); return rv; } } while (false); |
1179 | if (!organization.IsEmpty()) { |
1180 | whitelistString.AppendLiteral("/O="); |
1181 | whitelistString.Append( |
1182 | EscapeCertificateAttribute(NS_ConvertUTF16toUTF8(organization))); |
1183 | } |
1184 | |
1185 | nsString organizationalUnit; |
1186 | rv = certificate->GetOrganizationalUnit(organizationalUnit); |
1187 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1187); return rv; } } while (false); |
1188 | if (!organizationalUnit.IsEmpty()) { |
1189 | whitelistString.AppendLiteral("/OU="); |
1190 | whitelistString.Append( |
1191 | EscapeCertificateAttribute(NS_ConvertUTF16toUTF8(organizationalUnit))); |
1192 | } |
1193 | LOG(("Whitelisting %s", whitelistString.get()))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Whitelisting %s" , whitelistString.get()); } } while (0); |
1194 | |
1195 | mAllowlistSpecs.AppendElement(whitelistString); |
1196 | return NS_OK; |
1197 | } |
1198 | |
1199 | nsresult PendingLookup::GenerateWhitelistStringsForChain( |
1200 | const safe_browsing::ClientDownloadRequest_CertificateChain& aChain) { |
1201 | // We need a signing certificate and an issuer to construct a whitelist |
1202 | // entry. |
1203 | if (aChain.element_size() < 2) { |
1204 | return NS_OK; |
1205 | } |
1206 | |
1207 | // Get the signer. |
1208 | nsresult rv; |
1209 | nsCOMPtr<nsIX509CertDB> certDB = do_GetService(NS_X509CERTDB_CONTRACTID"@mozilla.org/security/x509certdb;1", &rv); |
1210 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1210); return rv; } } while (false); |
1211 | |
1212 | nsCOMPtr<nsIX509Cert> signer; |
1213 | nsTArray<uint8_t> signerBytes; |
1214 | signerBytes.AppendElements(aChain.element(0).certificate().data(), |
1215 | aChain.element(0).certificate().size()); |
1216 | rv = certDB->ConstructX509(signerBytes, getter_AddRefs(signer)); |
1217 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1217); return rv; } } while (false); |
1218 | |
1219 | for (int i = 1; i < aChain.element_size(); ++i) { |
1220 | // Get the issuer. |
1221 | nsCOMPtr<nsIX509Cert> issuer; |
1222 | nsTArray<uint8_t> issuerBytes; |
1223 | issuerBytes.AppendElements(aChain.element(i).certificate().data(), |
1224 | aChain.element(i).certificate().size()); |
1225 | rv = certDB->ConstructX509(issuerBytes, getter_AddRefs(issuer)); |
1226 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1226); return rv; } } while (false); |
1227 | |
1228 | rv = GenerateWhitelistStringsForPair(signer, issuer); |
1229 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1229); return rv; } } while (false); |
1230 | } |
1231 | return NS_OK; |
1232 | } |
1233 | |
1234 | nsresult PendingLookup::GenerateWhitelistStrings() { |
1235 | for (int i = 0; i < mRequest.signature().certificate_chain_size(); ++i) { |
1236 | nsresult rv = GenerateWhitelistStringsForChain( |
1237 | mRequest.signature().certificate_chain(i)); |
1238 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1238); return rv; } } while (false); |
1239 | } |
1240 | return NS_OK; |
1241 | } |
1242 | |
1243 | nsresult PendingLookup::AddRedirects(nsIArray* aRedirects) { |
1244 | uint32_t length = 0; |
1245 | aRedirects->GetLength(&length); |
1246 | LOG(("ApplicationReputation: Got %u redirects", length))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "ApplicationReputation: Got %u redirects" , length); } } while (0); |
1247 | nsCOMPtr<nsISimpleEnumerator> iter; |
1248 | nsresult rv = aRedirects->Enumerate(getter_AddRefs(iter)); |
1249 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1249); return rv; } } while (false); |
1250 | |
1251 | bool hasMoreRedirects = false; |
1252 | rv = iter->HasMoreElements(&hasMoreRedirects); |
1253 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1253); return rv; } } while (false); |
1254 | |
1255 | while (hasMoreRedirects) { |
1256 | nsCOMPtr<nsISupports> supports; |
1257 | rv = iter->GetNext(getter_AddRefs(supports)); |
1258 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1258); return rv; } } while (false); |
1259 | |
1260 | nsCOMPtr<nsIRedirectHistoryEntry> redirectEntry = |
1261 | do_QueryInterface(supports, &rv); |
1262 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1262); return rv; } } while (false); |
1263 | |
1264 | nsCOMPtr<nsIPrincipal> principal; |
1265 | rv = redirectEntry->GetPrincipal(getter_AddRefs(principal)); |
1266 | auto* basePrin = BasePrincipal::Cast(principal); |
1267 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1267); return rv; } } while (false); |
1268 | |
1269 | nsCOMPtr<nsIURI> uri; |
1270 | rv = basePrin->GetURI(getter_AddRefs(uri)); |
1271 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1271); return rv; } } while (false); |
1272 | |
1273 | // Add the spec to our list of local lookups. The most recent redirect is |
1274 | // the last element. |
1275 | nsCString spec; |
1276 | rv = GetStrippedSpec(uri, spec); |
1277 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1277); return rv; } } while (false); |
1278 | mBlocklistSpecs.AppendElement(spec); |
1279 | LOG(("ApplicationReputation: Appending redirect %s\n", spec.get()))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "ApplicationReputation: Appending redirect %s\n" , spec.get()); } } while (0); |
1280 | |
1281 | // Store the redirect information in the remote request. |
1282 | ClientDownloadRequest_Resource* resource = mRequest.add_resources(); |
1283 | resource->set_url(spec.get()); |
1284 | resource->set_type(ClientDownloadRequest::DOWNLOAD_REDIRECT); |
1285 | |
1286 | rv = iter->HasMoreElements(&hasMoreRedirects); |
1287 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1287); return rv; } } while (false); |
1288 | } |
1289 | return NS_OK; |
1290 | } |
1291 | |
1292 | nsresult PendingLookup::StartLookup() { |
1293 | mStartTime = TimeStamp::Now(); |
1294 | nsresult rv = DoLookupInternal(); |
1295 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
1296 | return OnComplete(nsIApplicationReputationService::VERDICT_SAFE, |
1297 | Reason::InternalError, NS_OK); |
1298 | } |
1299 | return rv; |
1300 | } |
1301 | |
1302 | nsresult PendingLookup::GetSpecHash(nsACString& aSpec, |
1303 | nsACString& hexEncodedHash) { |
1304 | nsCOMPtr<nsICryptoHash> cryptoHash; |
1305 | nsresult rv = |
1306 | NS_NewCryptoHash(nsICryptoHash::SHA256, getter_AddRefs(cryptoHash)); |
1307 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1307); return rv; } } while (false); |
1308 | |
1309 | rv = cryptoHash->Update( |
1310 | reinterpret_cast<const uint8_t*>(aSpec.BeginReading()), aSpec.Length()); |
1311 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1311); return rv; } } while (false); |
1312 | |
1313 | nsAutoCString binaryHash; |
1314 | rv = cryptoHash->Finish(false, binaryHash); |
1315 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1315); return rv; } } while (false); |
1316 | |
1317 | // This needs to match HexEncode() in Chrome's |
1318 | // src/base/strings/string_number_conversions.cc |
1319 | static const char* const hex = "0123456789ABCDEF"; |
1320 | hexEncodedHash.SetCapacity(2 * binaryHash.Length()); |
1321 | for (size_t i = 0; i < binaryHash.Length(); ++i) { |
1322 | auto c = static_cast<unsigned char>(binaryHash[i]); |
1323 | hexEncodedHash.Append(hex[(c >> 4) & 0x0F]); |
1324 | hexEncodedHash.Append(hex[c & 0x0F]); |
1325 | } |
1326 | |
1327 | return NS_OK; |
1328 | } |
1329 | |
1330 | nsresult PendingLookup::GetStrippedSpec(nsIURI* aUri, nsACString& escaped) { |
1331 | if (NS_WARN_IF(!aUri)NS_warn_if_impl(!aUri, "!aUri", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1331)) { |
1332 | return NS_ERROR_INVALID_ARG; |
1333 | } |
1334 | |
1335 | nsresult rv; |
1336 | rv = aUri->GetScheme(escaped); |
1337 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1337); return rv; } } while (false); |
1338 | |
1339 | if (escaped.EqualsLiteral("blob")) { |
1340 | aUri->GetSpec(escaped); |
1341 | LOG(do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): blob URL left unstripped as '%s' " "[this = %p]", TPromiseFlatString<char>(escaped).get() , this); } } while (0) |
1342 | ("PendingLookup::GetStrippedSpec(): blob URL left unstripped as '%s' "do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): blob URL left unstripped as '%s' " "[this = %p]", TPromiseFlatString<char>(escaped).get() , this); } } while (0) |
1343 | "[this = %p]",do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): blob URL left unstripped as '%s' " "[this = %p]", TPromiseFlatString<char>(escaped).get() , this); } } while (0) |
1344 | PromiseFlatCString(escaped).get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): blob URL left unstripped as '%s' " "[this = %p]", TPromiseFlatString<char>(escaped).get() , this); } } while (0); |
1345 | return NS_OK; |
1346 | } |
1347 | |
1348 | if (escaped.EqualsLiteral("data")) { |
1349 | // Replace URI with "data:<everything before comma>,SHA256(<whole URI>)" |
1350 | aUri->GetSpec(escaped); |
1351 | int32_t comma = escaped.FindChar(','); |
1352 | if (comma > -1 && |
1353 | static_cast<nsCString::size_type>(comma) < escaped.Length() - 1) { |
1354 | MOZ_ASSERT(comma > 4, "Data URIs start with 'data:'")do { static_assert( mozilla::detail::AssertionConditionType< decltype(comma > 4)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(comma > 4))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("comma > 4" " (" "Data URIs start with 'data:'" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1354); AnnotateMozCrashReason("MOZ_ASSERT" "(" "comma > 4" ") (" "Data URIs start with 'data:'" ")"); do { *((volatile int *)__null) = 1354; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); |
1355 | nsAutoCString hexEncodedHash; |
1356 | rv = GetSpecHash(escaped, hexEncodedHash); |
1357 | if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) { |
1358 | escaped.Truncate(comma + 1); |
1359 | escaped.Append(hexEncodedHash); |
1360 | } |
1361 | } |
1362 | |
1363 | LOG(do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): data URL stripped to '%s' [this = " "%p]", TPromiseFlatString<char>(escaped).get(), this); } } while (0) |
1364 | ("PendingLookup::GetStrippedSpec(): data URL stripped to '%s' [this = "do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): data URL stripped to '%s' [this = " "%p]", TPromiseFlatString<char>(escaped).get(), this); } } while (0) |
1365 | "%p]",do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): data URL stripped to '%s' [this = " "%p]", TPromiseFlatString<char>(escaped).get(), this); } } while (0) |
1366 | PromiseFlatCString(escaped).get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): data URL stripped to '%s' [this = " "%p]", TPromiseFlatString<char>(escaped).get(), this); } } while (0); |
1367 | return NS_OK; |
1368 | } |
1369 | |
1370 | // If aURI is not an nsIURL, we do not want to check the lists or send a |
1371 | // remote query. |
1372 | nsCOMPtr<nsIURL> url = do_QueryInterface(aUri, &rv); |
1373 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
1374 | LOG(do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): scheme '%s' is not supported [this " "= %p]", TPromiseFlatString<char>(escaped).get(), this ); } } while (0) |
1375 | ("PendingLookup::GetStrippedSpec(): scheme '%s' is not supported [this "do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): scheme '%s' is not supported [this " "= %p]", TPromiseFlatString<char>(escaped).get(), this ); } } while (0) |
1376 | "= %p]",do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): scheme '%s' is not supported [this " "= %p]", TPromiseFlatString<char>(escaped).get(), this ); } } while (0) |
1377 | PromiseFlatCString(escaped).get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): scheme '%s' is not supported [this " "= %p]", TPromiseFlatString<char>(escaped).get(), this ); } } while (0); |
1378 | return rv; |
1379 | } |
1380 | |
1381 | nsCString temp; |
1382 | rv = url->GetHostPort(temp); |
1383 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1383); return rv; } } while (false); |
1384 | |
1385 | escaped.AppendLiteral("://"); |
1386 | escaped.Append(temp); |
1387 | |
1388 | rv = url->GetFilePath(temp); |
1389 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1389); return rv; } } while (false); |
1390 | |
1391 | // nsIUrl.filePath starts with '/' |
1392 | escaped.Append(temp); |
1393 | |
1394 | LOG(("PendingLookup::GetStrippedSpec(): URL stripped to '%s' [this = %p]",do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): URL stripped to '%s' [this = %p]" , TPromiseFlatString<char>(escaped).get(), this); } } while (0) |
1395 | PromiseFlatCString(escaped).get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "PendingLookup::GetStrippedSpec(): URL stripped to '%s' [this = %p]" , TPromiseFlatString<char>(escaped).get(), this); } } while (0); |
1396 | return NS_OK; |
1397 | } |
1398 | |
1399 | nsresult PendingLookup::DoLookupInternal() { |
1400 | // We want to check the target URI, its referrer, and associated redirects |
1401 | // against the local lists. |
1402 | nsCOMPtr<nsIURI> uri; |
1403 | nsresult rv = mQuery->GetSourceURI(getter_AddRefs(uri)); |
1404 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1404); return rv; } } while (false); |
1405 | |
1406 | nsCString sourceSpec; |
1407 | rv = GetStrippedSpec(uri, sourceSpec); |
1408 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1408); return rv; } } while (false); |
1409 | |
1410 | mAnylistSpecs.AppendElement(sourceSpec); |
1411 | |
1412 | ClientDownloadRequest_Resource* resource = mRequest.add_resources(); |
1413 | resource->set_url(sourceSpec.get()); |
1414 | resource->set_type(ClientDownloadRequest::DOWNLOAD_URL); |
1415 | |
1416 | nsCOMPtr<nsIReferrerInfo> referrerInfo; |
1417 | mozilla::Unused << mQuery->GetReferrerInfo(getter_AddRefs(referrerInfo)); |
1418 | nsCOMPtr<nsIURI> referrer; |
1419 | // It is quite possible that referrer header is omitted due to security reason |
1420 | // (for example navigation from https-> http). Hence we should use the |
1421 | // original referrer which has not applied referrer policy yet, to make sure |
1422 | // we don't mistakenly allow unsafe download. |
1423 | if (referrerInfo) { |
1424 | referrer = referrerInfo->GetOriginalReferrer(); |
1425 | } |
1426 | |
1427 | if (referrer) { |
1428 | nsCString referrerSpec; |
1429 | rv = GetStrippedSpec(referrer, referrerSpec); |
1430 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1430); return rv; } } while (false); |
1431 | mBlocklistSpecs.AppendElement(referrerSpec); |
1432 | resource->set_referrer(referrerSpec.get()); |
1433 | } |
1434 | |
1435 | nsCOMPtr<nsIArray> redirects; |
1436 | rv = mQuery->GetRedirects(getter_AddRefs(redirects)); |
Value stored to 'rv' is never read | |
1437 | if (redirects) { |
1438 | AddRedirects(redirects); |
1439 | } else { |
1440 | LOG(("ApplicationReputation: Got no redirects [this=%p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "ApplicationReputation: Got no redirects [this=%p]" , this); } } while (0); |
1441 | } |
1442 | |
1443 | rv = mQuery->GetSuggestedFileName(mFileName); |
1444 | if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !mFileName.IsEmpty()) { |
1445 | mIsBinaryFile = IsBinary(mFileName); |
1446 | LOG(("Suggested filename: %s [binary = %d, this = %p]", mFileName.get(),do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Suggested filename: %s [binary = %d, this = %p]" , mFileName.get(), mIsBinaryFile, this); } } while (0) |
1447 | mIsBinaryFile, this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Suggested filename: %s [binary = %d, this = %p]" , mFileName.get(), mIsBinaryFile, this); } } while (0); |
1448 | } else { |
1449 | nsAutoCString errorName; |
1450 | mozilla::GetErrorName(rv, errorName); |
1451 | LOG(("No suggested filename [rv = %s, this = %p]", errorName.get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "No suggested filename [rv = %s, this = %p]" , errorName.get(), this); } } while (0); |
1452 | mFileName.Truncate(); |
1453 | } |
1454 | |
1455 | // We can skip parsing certificate for non-binary files because we only |
1456 | // check local block list for them. |
1457 | if (mIsBinaryFile) { |
1458 | nsTArray<nsTArray<nsTArray<uint8_t>>> sigArray; |
1459 | rv = mQuery->GetSignatureInfo(sigArray); |
1460 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1460); return rv; } } while (false); |
1461 | |
1462 | if (!sigArray.IsEmpty()) { |
1463 | rv = ParseCertificates(sigArray); |
1464 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1464); return rv; } } while (false); |
1465 | } |
1466 | |
1467 | rv = GenerateWhitelistStrings(); |
1468 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1468); return rv; } } while (false); |
1469 | } |
1470 | |
1471 | // Start the call chain. |
1472 | return LookupNext(); |
1473 | } |
1474 | |
1475 | nsresult PendingLookup::OnComplete(uint32_t aVerdict, Reason aReason, |
1476 | nsresult aRv) { |
1477 | if (NS_FAILED(aRv)((bool)(__builtin_expect(!!(NS_FAILED_impl(aRv)), 0)))) { |
1478 | nsAutoCString errorName; |
1479 | mozilla::GetErrorName(aRv, errorName); |
1480 | LOG(do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Failed sending remote query for application reputation " "[rv = %s, this = %p]", errorName.get(), this); } } while (0 ) |
1481 | ("Failed sending remote query for application reputation "do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Failed sending remote query for application reputation " "[rv = %s, this = %p]", errorName.get(), this); } } while (0 ) |
1482 | "[rv = %s, this = %p]",do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Failed sending remote query for application reputation " "[rv = %s, this = %p]", errorName.get(), this); } } while (0 ) |
1483 | errorName.get(), this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Failed sending remote query for application reputation " "[rv = %s, this = %p]", errorName.get(), this); } } while (0 ); |
1484 | } |
1485 | |
1486 | if (mTimeoutTimer) { |
1487 | mTimeoutTimer->Cancel(); |
1488 | mTimeoutTimer = nullptr; |
1489 | } |
1490 | |
1491 | bool shouldBlock = true; |
1492 | switch (aVerdict) { |
1493 | case nsIApplicationReputationService::VERDICT_DANGEROUS: |
1494 | if (!Preferences::GetBool(PREF_BLOCK_DANGEROUS"browser.safebrowsing.downloads.remote.block_dangerous", true)) { |
1495 | shouldBlock = false; |
1496 | aReason = Reason::DangerousPrefOff; |
1497 | } |
1498 | break; |
1499 | case nsIApplicationReputationService::VERDICT_UNCOMMON: |
1500 | if (!Preferences::GetBool(PREF_BLOCK_UNCOMMON"browser.safebrowsing.downloads.remote.block_uncommon", true)) { |
1501 | shouldBlock = false; |
1502 | aReason = Reason::UncommonPrefOff; |
1503 | } |
1504 | break; |
1505 | case nsIApplicationReputationService::VERDICT_POTENTIALLY_UNWANTED: |
1506 | if (!Preferences::GetBool(PREF_BLOCK_POTENTIALLY_UNWANTED"browser.safebrowsing.downloads.remote.block_potentially_unwanted", true)) { |
1507 | shouldBlock = false; |
1508 | aReason = Reason::UnwantedPrefOff; |
1509 | } |
1510 | break; |
1511 | case nsIApplicationReputationService::VERDICT_DANGEROUS_HOST: |
1512 | if (!Preferences::GetBool(PREF_BLOCK_DANGEROUS_HOST"browser.safebrowsing.downloads.remote.block_dangerous_host", true)) { |
1513 | shouldBlock = false; |
1514 | aReason = Reason::DangerousHostPrefOff; |
1515 | } |
1516 | break; |
1517 | default: |
1518 | shouldBlock = false; |
1519 | break; |
1520 | } |
1521 | |
1522 | AccumulateCategorical(aReason); |
1523 | Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_SHOULD_BLOCK, |
1524 | shouldBlock); |
1525 | |
1526 | double t = (TimeStamp::Now() - mStartTime).ToMilliseconds(); |
1527 | LOG(("Application Reputation verdict is %u, obtained in %f ms [this = %p]",do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Application Reputation verdict is %u, obtained in %f ms [this = %p]" , aVerdict, t, this); } } while (0) |
1528 | aVerdict, t, this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Application Reputation verdict is %u, obtained in %f ms [this = %p]" , aVerdict, t, this); } } while (0); |
1529 | if (shouldBlock) { |
1530 | LOG(("Application Reputation check failed, blocking bad binary [this = %p]",do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Application Reputation check failed, blocking bad binary [this = %p]" , this); } } while (0) |
1531 | this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Application Reputation check failed, blocking bad binary [this = %p]" , this); } } while (0); |
1532 | } else { |
1533 | LOG(("Application Reputation check passed [this = %p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Application Reputation check passed [this = %p]" , this); } } while (0); |
1534 | } |
1535 | |
1536 | nsresult res = mCallback->OnComplete(shouldBlock, aRv, aVerdict); |
1537 | return res; |
1538 | } |
1539 | |
1540 | nsresult PendingLookup::ParseCertificates( |
1541 | const nsTArray<nsTArray<nsTArray<uint8_t>>>& aSigArray) { |
1542 | // Binaries may be signed by multiple chains of certificates. If there are no |
1543 | // chains, the binary is unsigned (or we were unable to extract signature |
1544 | // information on a non-Windows platform) |
1545 | |
1546 | // Each chain may have multiple certificates. |
1547 | for (const auto& certList : aSigArray) { |
1548 | safe_browsing::ClientDownloadRequest_CertificateChain* certChain = |
1549 | mRequest.mutable_signature()->add_certificate_chain(); |
1550 | for (const auto& cert : certList) { |
1551 | // Add this certificate to the protobuf to send remotely. |
1552 | certChain->add_element()->set_certificate(cert.Elements(), cert.Length()); |
1553 | } |
1554 | } |
1555 | if (mRequest.signature().certificate_chain_size() > 0) { |
1556 | mRequest.mutable_signature()->set_trusted(true); |
1557 | } |
1558 | return NS_OK; |
1559 | } |
1560 | |
1561 | nsresult PendingLookup::SendRemoteQuery() { |
1562 | MOZ_ASSERT(!IsFileType(do { static_assert( mozilla::detail::AssertionConditionType< decltype(!IsFileType( mFileName, ApplicationReputationService ::kNonBinaryExecutables, ArrayLength(ApplicationReputationService ::kNonBinaryExecutables)))>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(!IsFileType( mFileName, ApplicationReputationService ::kNonBinaryExecutables, ArrayLength(ApplicationReputationService ::kNonBinaryExecutables))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure ("!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, ArrayLength(ApplicationReputationService::kNonBinaryExecutables))" , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1564); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, ArrayLength(ApplicationReputationService::kNonBinaryExecutables))" ")"); do { *((volatile int*)__null) = 1564; __attribute__((nomerge )) ::abort(); } while (false); } } while (false) |
1563 | mFileName, ApplicationReputationService::kNonBinaryExecutables,do { static_assert( mozilla::detail::AssertionConditionType< decltype(!IsFileType( mFileName, ApplicationReputationService ::kNonBinaryExecutables, ArrayLength(ApplicationReputationService ::kNonBinaryExecutables)))>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(!IsFileType( mFileName, ApplicationReputationService ::kNonBinaryExecutables, ArrayLength(ApplicationReputationService ::kNonBinaryExecutables))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure ("!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, ArrayLength(ApplicationReputationService::kNonBinaryExecutables))" , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1564); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, ArrayLength(ApplicationReputationService::kNonBinaryExecutables))" ")"); do { *((volatile int*)__null) = 1564; __attribute__((nomerge )) ::abort(); } while (false); } } while (false) |
1564 | ArrayLength(ApplicationReputationService::kNonBinaryExecutables)))do { static_assert( mozilla::detail::AssertionConditionType< decltype(!IsFileType( mFileName, ApplicationReputationService ::kNonBinaryExecutables, ArrayLength(ApplicationReputationService ::kNonBinaryExecutables)))>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(!IsFileType( mFileName, ApplicationReputationService ::kNonBinaryExecutables, ArrayLength(ApplicationReputationService ::kNonBinaryExecutables))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure ("!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, ArrayLength(ApplicationReputationService::kNonBinaryExecutables))" , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1564); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, ArrayLength(ApplicationReputationService::kNonBinaryExecutables))" ")"); do { *((volatile int*)__null) = 1564; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
1565 | Reason reason = Reason::NotSet; |
1566 | nsresult rv = SendRemoteQueryInternal(reason); |
1567 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
1568 | return OnComplete(nsIApplicationReputationService::VERDICT_SAFE, reason, |
1569 | rv); |
1570 | } |
1571 | // SendRemoteQueryInternal has fired off the query and we call OnComplete in |
1572 | // the nsIStreamListener.onStopRequest. |
1573 | return rv; |
1574 | } |
1575 | |
1576 | nsresult PendingLookup::SendRemoteQueryInternal(Reason& aReason) { |
1577 | auto scopeExit = mozilla::MakeScopeExit([&aReason]() { |
1578 | if (aReason == Reason::NotSet) { |
1579 | aReason = Reason::InternalError; |
1580 | } |
1581 | }); |
1582 | |
1583 | // If we aren't supposed to do remote lookups, bail. |
1584 | if (!Preferences::GetBool(PREF_SB_DOWNLOADS_REMOTE_ENABLED"browser.safebrowsing.downloads.remote.enabled", false)) { |
1585 | LOG(("Remote lookups are disabled [this = %p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Remote lookups are disabled [this = %p]" , this); } } while (0); |
1586 | aReason = Reason::RemoteLookupDisabled; |
1587 | return NS_ERROR_NOT_AVAILABLE; |
1588 | } |
1589 | // If the remote lookup URL is empty or absent, bail. |
1590 | nsString serviceUrl; |
1591 | nsCOMPtr<nsIURLFormatter> formatter( |
1592 | do_GetService("@mozilla.org/toolkit/URLFormatterService;1")); |
1593 | if (!formatter || |
1594 | NS_FAILED(formatter->FormatURLPref(((bool)(__builtin_expect(!!(NS_FAILED_impl(formatter->FormatURLPref ( NS_ConvertASCIItoUTF16("browser.safebrowsing.downloads.remote.url" ), serviceUrl))), 0))) |
1595 | NS_ConvertASCIItoUTF16(PREF_SB_APP_REP_URL), serviceUrl))((bool)(__builtin_expect(!!(NS_FAILED_impl(formatter->FormatURLPref ( NS_ConvertASCIItoUTF16("browser.safebrowsing.downloads.remote.url" ), serviceUrl))), 0))) || |
1596 | serviceUrl.IsEmpty() || u"about:blank"_ns.Equals(serviceUrl)) { |
1597 | LOG(("Remote lookup URL is empty or absent [this = %p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Remote lookup URL is empty or absent [this = %p]" , this); } } while (0); |
1598 | aReason = Reason::RemoteLookupDisabled; |
1599 | return NS_ERROR_NOT_AVAILABLE; |
1600 | } |
1601 | |
1602 | LOG(("Sending remote query for application reputation [this = %p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Sending remote query for application reputation [this = %p]" , this); } } while (0); |
1603 | // We did not find a local result, so fire off the query to the |
1604 | // application reputation service. |
1605 | nsCOMPtr<nsIURI> uri; |
1606 | nsresult rv; |
1607 | rv = mQuery->GetSourceURI(getter_AddRefs(uri)); |
1608 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1608); return rv; } } while (false); |
1609 | nsCString spec; |
1610 | rv = GetStrippedSpec(uri, spec); |
1611 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1611); return rv; } } while (false); |
1612 | mRequest.set_url(spec.get()); |
1613 | |
1614 | uint32_t fileSize; |
1615 | rv = mQuery->GetFileSize(&fileSize); |
1616 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1616); return rv; } } while (false); |
1617 | mRequest.set_length(fileSize); |
1618 | // We have no way of knowing whether or not a user initiated the |
1619 | // download. Set it to true to lessen the chance of false positives. |
1620 | mRequest.set_user_initiated(true); |
1621 | |
1622 | nsCString locale; |
1623 | rv = LocaleService::GetInstance()->GetAppLocaleAsBCP47(locale); |
1624 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1624); return rv; } } while (false); |
1625 | mRequest.set_locale(locale.get()); |
1626 | nsCString sha256Hash; |
1627 | rv = mQuery->GetSha256Hash(sha256Hash); |
1628 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1628); return rv; } } while (false); |
1629 | mRequest.mutable_digests()->set_sha256( |
1630 | std::string(sha256Hash.Data(), sha256Hash.Length())); |
1631 | mRequest.set_file_basename(mFileName.get()); |
1632 | mRequest.set_download_type(GetDownloadType(mFileName)); |
1633 | |
1634 | if (mRequest.signature().trusted()) { |
1635 | LOG(do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Got signed binary for remote application reputation check " "[this = %p]", this); } } while (0) |
1636 | ("Got signed binary for remote application reputation check "do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Got signed binary for remote application reputation check " "[this = %p]", this); } } while (0) |
1637 | "[this = %p]",do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Got signed binary for remote application reputation check " "[this = %p]", this); } } while (0) |
1638 | this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Got signed binary for remote application reputation check " "[this = %p]", this); } } while (0); |
1639 | } else { |
1640 | LOG(do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Got unsigned binary for remote application reputation check " "[this = %p]", this); } } while (0) |
1641 | ("Got unsigned binary for remote application reputation check "do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Got unsigned binary for remote application reputation check " "[this = %p]", this); } } while (0) |
1642 | "[this = %p]",do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Got unsigned binary for remote application reputation check " "[this = %p]", this); } } while (0) |
1643 | this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Got unsigned binary for remote application reputation check " "[this = %p]", this); } } while (0); |
1644 | } |
1645 | |
1646 | // Serialize the protocol buffer to a string. This can only fail if we are |
1647 | // out of memory, or if the protocol buffer req is missing required fields |
1648 | // (only the URL for now). |
1649 | std::string serialized; |
1650 | if (!mRequest.SerializeToString(&serialized)) { |
1651 | return NS_ERROR_UNEXPECTED; |
1652 | } |
1653 | |
1654 | if (LOG_ENABLED()(__builtin_expect(!!(mozilla::detail::log_test(ApplicationReputationService ::prlog, mozilla::LogLevel::Debug)), 0))) { |
1655 | nsAutoCString serializedStr(serialized.c_str(), serialized.length()); |
1656 | serializedStr.ReplaceSubstring("\0"_ns, "\\0"_ns); |
1657 | |
1658 | LOG(("Serialized protocol buffer [this = %p]: (length=%zd) %s", this,do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Serialized protocol buffer [this = %p]: (length=%zd) %s" , this, serializedStr.Length(), serializedStr.get()); } } while (0) |
1659 | serializedStr.Length(), serializedStr.get()))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Serialized protocol buffer [this = %p]: (length=%zd) %s" , this, serializedStr.Length(), serializedStr.get()); } } while (0); |
1660 | } |
1661 | |
1662 | // Set the input stream to the serialized protocol buffer |
1663 | nsCOMPtr<nsIStringInputStream> sstream = |
1664 | do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv); |
1665 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1665); return rv; } } while (false); |
1666 | |
1667 | rv = sstream->SetData(serialized.c_str(), serialized.length()); |
1668 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1668); return rv; } } while (false); |
1669 | |
1670 | // Set up the channel to transmit the request to the service. |
1671 | nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID"@mozilla.org/network/io-service;1", &rv); |
1672 | rv = ios->NewChannel(NS_ConvertUTF16toUTF8(serviceUrl), nullptr, nullptr, |
1673 | nullptr, // aLoadingNode |
1674 | nsContentUtils::GetSystemPrincipal(), |
1675 | nullptr, // aTriggeringPrincipal |
1676 | nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, |
1677 | nsIContentPolicy::TYPE_OTHER, getter_AddRefs(mChannel)); |
1678 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1678); return rv; } } while (false); |
1679 | |
1680 | mChannel->SetLoadFlags(nsIChannel::LOAD_BYPASS_URL_CLASSIFIER); |
1681 | |
1682 | nsCOMPtr<nsILoadInfo> loadInfo = mChannel->LoadInfo(); |
1683 | mozilla::OriginAttributes attrs; |
1684 | attrs.mFirstPartyDomain.AssignLiteral(NECKO_SAFEBROWSING_FIRST_PARTY_DOMAIN"safebrowsing.86868755-6b82-4842-b301-72671a0db32e.mozilla"); |
1685 | loadInfo->SetOriginAttributes(attrs); |
1686 | |
1687 | nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel, &rv)); |
1688 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1688); return rv; } } while (false); |
1689 | mozilla::Unused << httpChannel; |
1690 | |
1691 | // Upload the protobuf to the application reputation service. |
1692 | nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(mChannel, &rv); |
1693 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1693); return rv; } } while (false); |
1694 | |
1695 | rv = uploadChannel->ExplicitSetUploadStream( |
1696 | sstream, "application/octet-stream"_ns, serialized.size(), "POST"_ns, |
1697 | false); |
1698 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1698); return rv; } } while (false); |
1699 | |
1700 | uint32_t timeoutMs = |
1701 | Preferences::GetUint(PREF_SB_DOWNLOADS_REMOTE_TIMEOUT"browser.safebrowsing.downloads.remote.timeout_ms", 10000); |
1702 | NS_NewTimerWithCallback(getter_AddRefs(mTimeoutTimer), this, timeoutMs, |
1703 | nsITimer::TYPE_ONE_SHOT); |
1704 | |
1705 | mTelemetryRemoteRequestStartMs = PR_IntervalNow(); |
1706 | |
1707 | rv = mChannel->AsyncOpen(this); |
1708 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1708); return rv; } } while (false); |
1709 | |
1710 | return NS_OK; |
1711 | } |
1712 | |
1713 | NS_IMETHODIMPnsresult |
1714 | PendingLookup::Notify(nsITimer* aTimer) { |
1715 | LOG(("Remote lookup timed out [this = %p]", this))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Remote lookup timed out [this = %p]" , this); } } while (0); |
1716 | MOZ_ASSERT(aTimer == mTimeoutTimer)do { static_assert( mozilla::detail::AssertionConditionType< decltype(aTimer == mTimeoutTimer)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(aTimer == mTimeoutTimer))), 0 ))) { do { } while (false); MOZ_ReportAssertionFailure("aTimer == mTimeoutTimer" , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1716); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aTimer == mTimeoutTimer" ")"); do { *((volatile int*)__null) = 1716; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
1717 | Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_REMOTE_LOOKUP_TIMEOUT, |
1718 | true); |
1719 | mChannel->Cancel(NS_ERROR_NET_TIMEOUT_EXTERNAL); |
1720 | mTimeoutTimer->Cancel(); |
1721 | return NS_OK; |
1722 | } |
1723 | |
1724 | NS_IMETHODIMPnsresult |
1725 | PendingLookup::GetName(nsACString& aName) { |
1726 | aName.AssignLiteral("PendingLookup"); |
1727 | return NS_OK; |
1728 | } |
1729 | |
1730 | /////////////////////////////////////////////////////////////////////////////// |
1731 | // nsIObserver implementation |
1732 | NS_IMETHODIMPnsresult |
1733 | PendingLookup::Observe(nsISupports* aSubject, const char* aTopic, |
1734 | const char16_t* aData) { |
1735 | if (!strcmp(aTopic, "quit-application")) { |
1736 | if (mTimeoutTimer) { |
1737 | mTimeoutTimer->Cancel(); |
1738 | mTimeoutTimer = nullptr; |
1739 | } |
1740 | if (mChannel) { |
1741 | mChannel->Cancel(NS_ERROR_ABORT); |
1742 | } |
1743 | } |
1744 | return NS_OK; |
1745 | } |
1746 | |
1747 | //////////////////////////////////////////////////////////////////////////////// |
1748 | //// nsIStreamListener |
1749 | static nsresult AppendSegmentToString(nsIInputStream* inputStream, |
1750 | void* closure, const char* rawSegment, |
1751 | uint32_t toOffset, uint32_t count, |
1752 | uint32_t* writeCount) { |
1753 | nsAutoCString* decodedData = static_cast<nsAutoCString*>(closure); |
1754 | decodedData->Append(rawSegment, count); |
1755 | *writeCount = count; |
1756 | return NS_OK; |
1757 | } |
1758 | |
1759 | NS_IMETHODIMPnsresult |
1760 | PendingLookup::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aStream, |
1761 | uint64_t offset, uint32_t count) { |
1762 | uint32_t read; |
1763 | return aStream->ReadSegments(AppendSegmentToString, &mResponse, count, &read); |
1764 | } |
1765 | |
1766 | NS_IMETHODIMPnsresult |
1767 | PendingLookup::OnStartRequest(nsIRequest* aRequest) { return NS_OK; } |
1768 | |
1769 | NS_IMETHODIMPnsresult |
1770 | PendingLookup::OnStopRequest(nsIRequest* aRequest, nsresult aResult) { |
1771 | NS_ENSURE_STATE(mCallback)do { if ((__builtin_expect(!!(!(mCallback)), 0))) { NS_DebugBreak (NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mCallback" ") failed", nullptr , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1771); return NS_ERROR_UNEXPECTED; } } while (false); |
1772 | |
1773 | if (aResult != NS_ERROR_NET_TIMEOUT_EXTERNAL) { |
1774 | Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_REMOTE_LOOKUP_TIMEOUT, |
1775 | false); |
1776 | |
1777 | MOZ_ASSERT(mTelemetryRemoteRequestStartMs > 0)do { static_assert( mozilla::detail::AssertionConditionType< decltype(mTelemetryRemoteRequestStartMs > 0)>::isValid, "invalid assertion condition"); if ((__builtin_expect(!!(!(! !(mTelemetryRemoteRequestStartMs > 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("mTelemetryRemoteRequestStartMs > 0" , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1777); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mTelemetryRemoteRequestStartMs > 0" ")"); do { *((volatile int*)__null) = 1777; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
1778 | int32_t msecs = PR_IntervalToMilliseconds(PR_IntervalNow() - |
1779 | mTelemetryRemoteRequestStartMs); |
1780 | |
1781 | MOZ_ASSERT(msecs >= 0)do { static_assert( mozilla::detail::AssertionConditionType< decltype(msecs >= 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(msecs >= 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("msecs >= 0", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1781); AnnotateMozCrashReason("MOZ_ASSERT" "(" "msecs >= 0" ")"); do { *((volatile int*)__null) = 1781; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
1782 | mozilla::Telemetry::Accumulate( |
1783 | mozilla::Telemetry::APPLICATION_REPUTATION_REMOTE_LOOKUP_RESPONSE_TIME, |
1784 | msecs); |
1785 | } |
1786 | |
1787 | uint32_t verdict = nsIApplicationReputationService::VERDICT_SAFE; |
1788 | Reason reason = Reason::NotSet; |
1789 | nsresult rv = OnStopRequestInternal(aRequest, aResult, verdict, reason); |
1790 | OnComplete(verdict, reason, rv); |
1791 | return rv; |
1792 | } |
1793 | |
1794 | nsresult PendingLookup::OnStopRequestInternal(nsIRequest* aRequest, |
1795 | nsresult aResult, |
1796 | uint32_t& aVerdict, |
1797 | Reason& aReason) { |
1798 | auto scopeExit = mozilla::MakeScopeExit([&aReason]() { |
1799 | // If |aReason| is not set while exiting, there must be an error. |
1800 | if (aReason == Reason::NotSet) { |
1801 | aReason = Reason::NetworkError; |
1802 | } |
1803 | }); |
1804 | |
1805 | if (NS_FAILED(aResult)((bool)(__builtin_expect(!!(NS_FAILED_impl(aResult)), 0)))) { |
1806 | Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_SERVER, |
1807 | SERVER_RESPONSE_FAILED); |
1808 | AccumulateCategorical(NSErrorToLabel(aResult)); |
1809 | return aResult; |
1810 | } |
1811 | |
1812 | nsresult rv; |
1813 | nsCOMPtr<nsIHttpChannel> channel = do_QueryInterface(aRequest, &rv); |
1814 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
1815 | Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_SERVER, |
1816 | SERVER_RESPONSE_FAILED); |
1817 | AccumulateCategorical( |
1818 | mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_SERVER_2:: |
1819 | FailGetChannel); |
1820 | return rv; |
1821 | } |
1822 | |
1823 | uint32_t status = 0; |
1824 | rv = channel->GetResponseStatus(&status); |
1825 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
1826 | Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_SERVER, |
1827 | SERVER_RESPONSE_FAILED); |
1828 | AccumulateCategorical( |
1829 | mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_SERVER_2:: |
1830 | FailGetResponse); |
1831 | return rv; |
1832 | } |
1833 | |
1834 | if (status != 200) { |
1835 | Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_SERVER, |
1836 | SERVER_RESPONSE_FAILED); |
1837 | AccumulateCategorical(HTTPStatusToLabel(status)); |
1838 | return NS_ERROR_NOT_AVAILABLE; |
1839 | } |
1840 | |
1841 | std::string buf(mResponse.Data(), mResponse.Length()); |
1842 | safe_browsing::ClientDownloadResponse response; |
1843 | if (!response.ParseFromString(buf)) { |
1844 | LOG(("Invalid protocol buffer response [this = %p]: %s", this,do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Invalid protocol buffer response [this = %p]: %s" , this, buf.c_str()); } } while (0) |
1845 | buf.c_str()))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Invalid protocol buffer response [this = %p]: %s" , this, buf.c_str()); } } while (0); |
1846 | Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_SERVER, |
1847 | SERVER_RESPONSE_INVALID); |
1848 | return NS_ERROR_CANNOT_CONVERT_DATA; |
1849 | } |
1850 | |
1851 | Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_SERVER, |
1852 | SERVER_RESPONSE_VALID); |
1853 | AccumulateCategorical( |
1854 | mozilla::Telemetry::LABELS_APPLICATION_REPUTATION_SERVER_2:: |
1855 | ResponseValid); |
1856 | |
1857 | // Clamp responses 0-7, we only know about 0-4 for now. |
1858 | Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_SERVER_VERDICT, |
1859 | std::min<uint32_t>(response.verdict(), 7)); |
1860 | const char* ext = GetFileExt(mFileName); |
1861 | AccumulateCategoricalKeyed(nsCString(ext), VerdictToLabel(std::min<uint32_t>( |
1862 | response.verdict(), 7))); |
1863 | switch (response.verdict()) { |
1864 | case safe_browsing::ClientDownloadResponse::DANGEROUS: |
1865 | aVerdict = nsIApplicationReputationService::VERDICT_DANGEROUS; |
1866 | aReason = Reason::VerdictDangerous; |
1867 | break; |
1868 | case safe_browsing::ClientDownloadResponse::DANGEROUS_HOST: |
1869 | aVerdict = nsIApplicationReputationService::VERDICT_DANGEROUS_HOST; |
1870 | aReason = Reason::VerdictDangerousHost; |
1871 | break; |
1872 | case safe_browsing::ClientDownloadResponse::POTENTIALLY_UNWANTED: |
1873 | aVerdict = nsIApplicationReputationService::VERDICT_POTENTIALLY_UNWANTED; |
1874 | aReason = Reason::VerdictUnwanted; |
1875 | break; |
1876 | case safe_browsing::ClientDownloadResponse::UNCOMMON: |
1877 | aVerdict = nsIApplicationReputationService::VERDICT_UNCOMMON; |
1878 | aReason = Reason::VerdictUncommon; |
1879 | break; |
1880 | case safe_browsing::ClientDownloadResponse::UNKNOWN: |
1881 | aVerdict = nsIApplicationReputationService::VERDICT_SAFE; |
1882 | aReason = Reason::VerdictUnknown; |
1883 | break; |
1884 | case safe_browsing::ClientDownloadResponse::SAFE: |
1885 | aVerdict = nsIApplicationReputationService::VERDICT_SAFE; |
1886 | aReason = Reason::VerdictSafe; |
1887 | break; |
1888 | default: |
1889 | // Treat everything else as safe |
1890 | aVerdict = nsIApplicationReputationService::VERDICT_SAFE; |
1891 | aReason = Reason::VerdictUnrecognized; |
1892 | break; |
1893 | } |
1894 | |
1895 | return NS_OK; |
1896 | } |
1897 | |
1898 | NS_IMPL_ISUPPORTS(ApplicationReputationService, nsIApplicationReputationService)MozExternalRefCountType ApplicationReputationService::AddRef( void) { static_assert(!std::is_destructible_v<ApplicationReputationService >, "Reference-counted class " "ApplicationReputationService" " should not have a public destructor. " "Make this class's destructor non-public" ); do { static_assert( mozilla::detail::AssertionConditionType <decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0" " (" "illegal refcnt" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1898); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0" ") (" "illegal refcnt" ")"); do { *((volatile int*)__null) = 1898; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("ApplicationReputationService" != nullptr)>:: isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!("ApplicationReputationService" != nullptr))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"ApplicationReputationService\" != nullptr" " (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1898); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"ApplicationReputationService\" != nullptr" ") (" "Must specify a name" ")"); do { *((volatile int*)__null ) = 1898; __attribute__((nomerge)) ::abort(); } while (false) ; } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread .AssertOwnership("ApplicationReputationService" " not thread-safe" ); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), ( "ApplicationReputationService"), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType ApplicationReputationService ::Release(void) { do { static_assert( mozilla::detail::AssertionConditionType <decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition" ); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0 ))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " (" "dup release" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1898); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0" ") (" "dup release" ")"); do { *((volatile int*)__null) = 1898 ; __attribute__((nomerge)) ::abort(); } while (false); } } while (false); do { static_assert( mozilla::detail::AssertionConditionType <decltype("ApplicationReputationService" != nullptr)>:: isValid, "invalid assertion condition"); if ((__builtin_expect (!!(!(!!("ApplicationReputationService" != nullptr))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"ApplicationReputationService\" != nullptr" " (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1898); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"ApplicationReputationService\" != nullptr" ") (" "Must specify a name" ")"); do { *((volatile int*)__null ) = 1898; __attribute__((nomerge)) ::abort(); } while (false) ; } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread .AssertOwnership("ApplicationReputationService" " not thread-safe" ); const char* const nametmp = "ApplicationReputationService" ; nsrefcnt count = --mRefCnt; NS_LogRelease((this), (count), ( nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return 0; } return count; } nsresult ApplicationReputationService:: QueryInterface(const nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!" , "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1898); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE ; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE" ); static const QITableEntry table[] = { {&mozilla::detail ::kImplementedIID<ApplicationReputationService, nsIApplicationReputationService >, int32_t( reinterpret_cast<char*>(static_cast<nsIApplicationReputationService *>((ApplicationReputationService*)0x1000)) - reinterpret_cast <char*>((ApplicationReputationService*)0x1000))}, {& mozilla::detail::kImplementedIID<ApplicationReputationService , nsISupports>, int32_t(reinterpret_cast<char*>(static_cast <nsISupports*>( static_cast<nsIApplicationReputationService *>((ApplicationReputationService*)0x1000))) - reinterpret_cast <char*>((ApplicationReputationService*)0x1000))}, { nullptr , 0 } } ; static_assert((sizeof(table) / sizeof(table[0])) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI(static_cast <void*>(this), aIID, aInstancePtr, table); return rv; } |
1899 | |
1900 | ApplicationReputationService* |
1901 | ApplicationReputationService::gApplicationReputationService = nullptr; |
1902 | |
1903 | already_AddRefed<ApplicationReputationService> |
1904 | ApplicationReputationService::GetSingleton() { |
1905 | if (!gApplicationReputationService) { |
1906 | // Note: This is cleared in the new ApplicationReputationService destructor. |
1907 | gApplicationReputationService = new ApplicationReputationService(); |
1908 | } |
1909 | return do_AddRef(gApplicationReputationService); |
1910 | } |
1911 | |
1912 | ApplicationReputationService::ApplicationReputationService() { |
1913 | LOG(("Application reputation service started up"))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Application reputation service started up" ); } } while (0); |
1914 | } |
1915 | |
1916 | ApplicationReputationService::~ApplicationReputationService() { |
1917 | LOG(("Application reputation service shutting down"))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Application reputation service shutting down" ); } } while (0); |
1918 | MOZ_ASSERT(gApplicationReputationService == this)do { static_assert( mozilla::detail::AssertionConditionType< decltype(gApplicationReputationService == this)>::isValid, "invalid assertion condition"); if ((__builtin_expect(!!(!(! !(gApplicationReputationService == this))), 0))) { do { } while (false); MOZ_ReportAssertionFailure("gApplicationReputationService == this" , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1918); AnnotateMozCrashReason("MOZ_ASSERT" "(" "gApplicationReputationService == this" ")"); do { *((volatile int*)__null) = 1918; __attribute__((nomerge )) ::abort(); } while (false); } } while (false); |
1919 | gApplicationReputationService = nullptr; |
1920 | } |
1921 | |
1922 | NS_IMETHODIMPnsresult |
1923 | ApplicationReputationService::QueryReputation( |
1924 | nsIApplicationReputationQuery* aQuery, |
1925 | nsIApplicationReputationCallback* aCallback) { |
1926 | LOG(("Starting application reputation check [query=%p]", aQuery))do { const ::mozilla::LogModule* moz_real_module = ApplicationReputationService ::prlog; if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module , mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print (moz_real_module, mozilla::LogLevel::Debug, "Starting application reputation check [query=%p]" , aQuery); } } while (0); |
1927 | NS_ENSURE_ARG_POINTER(aQuery)do { if ((__builtin_expect(!!(!(aQuery)), 0))) { NS_DebugBreak (NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aQuery" ") failed", nullptr , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1927); return NS_ERROR_INVALID_POINTER; } } while (false); |
1928 | NS_ENSURE_ARG_POINTER(aCallback)do { if ((__builtin_expect(!!(!(aCallback)), 0))) { NS_DebugBreak (NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aCallback" ") failed", nullptr , "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1928); return NS_ERROR_INVALID_POINTER; } } while (false); |
1929 | |
1930 | nsresult rv = QueryReputationInternal(aQuery, aCallback); |
1931 | if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) { |
1932 | Reason reason = rv == NS_ERROR_NOT_AVAILABLE ? Reason::DPDisabled |
1933 | : Reason::InternalError; |
1934 | |
1935 | AccumulateCategorical(reason); |
1936 | Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_SHOULD_BLOCK, false); |
1937 | |
1938 | aCallback->OnComplete(false, rv, |
1939 | nsIApplicationReputationService::VERDICT_SAFE); |
1940 | } |
1941 | return NS_OK; |
1942 | } |
1943 | |
1944 | nsresult ApplicationReputationService::QueryReputationInternal( |
1945 | nsIApplicationReputationQuery* aQuery, |
1946 | nsIApplicationReputationCallback* aCallback) { |
1947 | // If malware checks aren't enabled, don't query application reputation. |
1948 | if (!Preferences::GetBool(PREF_SB_MALWARE_ENABLED"browser.safebrowsing.malware.enabled", false)) { |
1949 | return NS_ERROR_NOT_AVAILABLE; |
1950 | } |
1951 | |
1952 | if (!Preferences::GetBool(PREF_SB_DOWNLOADS_ENABLED"browser.safebrowsing.downloads.enabled", false)) { |
1953 | return NS_ERROR_NOT_AVAILABLE; |
1954 | } |
1955 | |
1956 | nsCOMPtr<nsIURI> uri; |
1957 | nsresult rv = aQuery->GetSourceURI(getter_AddRefs(uri)); |
1958 | NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl (__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName (__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t >(__rv), name ? " (" : "", name ? name : "", name ? ")" : "" ); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1958); return rv; } } while (false); |
1959 | // Bail if the URI hasn't been set. |
1960 | NS_ENSURE_STATE(uri)do { if ((__builtin_expect(!!(!(uri)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING , "NS_ENSURE_TRUE(" "uri" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp" , 1960); return NS_ERROR_UNEXPECTED; } } while (false); |
1961 | |
1962 | // Create a new pending lookup and start the call chain. |
1963 | RefPtr<PendingLookup> lookup(new PendingLookup(aQuery, aCallback)); |
1964 | |
1965 | // Add an observer for shutdown |
1966 | nsCOMPtr<nsIObserverService> observerService = |
1967 | mozilla::services::GetObserverService(); |
1968 | if (!observerService) { |
1969 | return NS_ERROR_FAILURE; |
1970 | } |
1971 | |
1972 | observerService->AddObserver(lookup, "quit-application", true); |
1973 | return lookup->StartLookup(); |
1974 | } |
1975 | |
1976 | nsresult ApplicationReputationService::IsBinary(const nsACString& aFileName, |
1977 | bool* aBinary) { |
1978 | *aBinary = ::IsBinary(aFileName); |
1979 | return NS_OK; |
1980 | } |
1981 | |
1982 | nsresult ApplicationReputationService::IsExecutable(const nsACString& aFileName, |
1983 | bool* aExecutable) { |
1984 | *aExecutable = |
1985 | ::IsFileType(aFileName, sExecutableExts, ArrayLength(sExecutableExts)); |
1986 | return NS_OK; |
1987 | } |