Bug Summary

File:root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/components/reputationservice/./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp
Warning:line 1455, column 3
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_reputationservice0.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/components/reputationservice -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/components/reputationservice -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D GOOGLE_PROTOBUF_NO_RTTI -D GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/toolkit/components/reputationservice -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/components/reputationservice -I /root/firefox-clang/toolkit/components/protobuf -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/toolkit/components/reputationservice/chromium -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/third_party/abseil-cpp -I /root/firefox-clang/toolkit/components/telemetry -I /root/firefox-clang/xpcom/base -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c++ Unified_cpp_reputationservice0.cpp
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4// See
5// https://wiki.mozilla.org/Security/Features/Application_Reputation_Design_Doc
6// for a description of Chrome's implementation of this feature.
7#include "ApplicationReputation.h"
8#include "chrome/common/safe_browsing/csd.pb.h"
9
10#include "nsIArray.h"
11#include "nsIApplicationReputation.h"
12#include "nsIChannel.h"
13#include "nsIHttpChannel.h"
14#include "nsIIOService.h"
15#include "nsIObserverService.h"
16#include "nsISimpleEnumerator.h"
17#include "nsIStreamListener.h"
18#include "nsIStringStream.h"
19#include "nsITimer.h"
20#include "nsIUploadChannel2.h"
21#include "nsIURI.h"
22#include "nsIURL.h"
23#include "nsIUrlClassifierDBService.h"
24#include "nsIURLFormatter.h"
25#include "nsIX509Cert.h"
26#include "nsIX509CertDB.h"
27
28#include "mozilla/BasePrincipal.h"
29#include "mozilla/Components.h"
30#include "mozilla/ErrorNames.h"
31#include "mozilla/LoadContext.h"
32#include "mozilla/Preferences.h"
33#include "mozilla/ScopeExit.h"
34#include "mozilla/Services.h"
35#include "mozilla/glean/ReputationserviceMetrics.h"
36#include "mozilla/TimeStamp.h"
37#include "mozilla/intl/LocaleService.h"
38
39#include "nsCOMPtr.h"
40#include "nsDebug.h"
41#include "nsDependentSubstring.h"
42#include "nsError.h"
43#include "nsLocalFileCommon.h"
44#include "nsNetCID.h"
45#include "nsReadableUtils.h"
46#include "nsServiceManagerUtils.h"
47#include "nsString.h"
48#include "nsTArray.h"
49#include "nsThreadUtils.h"
50
51#include "nsIContentPolicy.h"
52#include "nsICryptoHash.h"
53#include "nsILoadInfo.h"
54#include "nsContentUtils.h"
55#include "nsWeakReference.h"
56#include "nsIRedirectHistoryEntry.h"
57
58#include "ApplicationReputationTelemetryUtils.h"
59
60using mozilla::BasePrincipal;
61using mozilla::OriginAttributes;
62using mozilla::Preferences;
63using mozilla::TimeStamp;
64using mozilla::intl::LocaleService;
65using safe_browsing::ClientDownloadRequest;
66using safe_browsing::ClientDownloadRequest_CertificateChain;
67using safe_browsing::ClientDownloadRequest_Resource;
68using safe_browsing::ClientDownloadRequest_SignatureInfo;
69
70// Preferences that we need to initialize the query.
71#define PREF_SB_APP_REP_URL"browser.safebrowsing.downloads.remote.url" "browser.safebrowsing.downloads.remote.url"
72#define PREF_SB_MALWARE_ENABLED"browser.safebrowsing.malware.enabled" "browser.safebrowsing.malware.enabled"
73#define PREF_SB_DOWNLOADS_ENABLED"browser.safebrowsing.downloads.enabled" "browser.safebrowsing.downloads.enabled"
74#define PREF_SB_DOWNLOADS_REMOTE_ENABLED"browser.safebrowsing.downloads.remote.enabled" \
75 "browser.safebrowsing.downloads.remote.enabled"
76#define PREF_SB_DOWNLOADS_REMOTE_TIMEOUT"browser.safebrowsing.downloads.remote.timeout_ms" \
77 "browser.safebrowsing.downloads.remote.timeout_ms"
78#define PREF_DOWNLOAD_BLOCK_TABLE"urlclassifier.downloadBlockTable" "urlclassifier.downloadBlockTable"
79#define PREF_DOWNLOAD_ALLOW_TABLE"urlclassifier.downloadAllowTable" "urlclassifier.downloadAllowTable"
80
81// Preferences that are needed to action the verdict.
82#define PREF_BLOCK_DANGEROUS"browser.safebrowsing.downloads.remote.block_dangerous" \
83 "browser.safebrowsing.downloads.remote.block_dangerous"
84#define PREF_BLOCK_DANGEROUS_HOST"browser.safebrowsing.downloads.remote.block_dangerous_host" \
85 "browser.safebrowsing.downloads.remote.block_dangerous_host"
86#define PREF_BLOCK_POTENTIALLY_UNWANTED"browser.safebrowsing.downloads.remote.block_potentially_unwanted" \
87 "browser.safebrowsing.downloads.remote.block_potentially_unwanted"
88#define PREF_BLOCK_UNCOMMON"browser.safebrowsing.downloads.remote.block_uncommon" \
89 "browser.safebrowsing.downloads.remote.block_uncommon"
90
91// MOZ_LOG=ApplicationReputation:5
92mozilla::LazyLogModule ApplicationReputationService::prlog(
93 "ApplicationReputation");
94#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)
\
95 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)
96#define LOG_ENABLED()(__builtin_expect(!!(mozilla::detail::log_test(ApplicationReputationService
::prlog, mozilla::LogLevel::Debug)), 0))
\
97 MOZ_LOG_TEST(ApplicationReputationService::prlog, mozilla::LogLevel::Debug)(__builtin_expect(!!(mozilla::detail::log_test(ApplicationReputationService
::prlog, mozilla::LogLevel::Debug)), 0))
98
99/**
100 * Our detection of executable/binary files uses 3 lists:
101 * - kNonBinaryExecutables (below)
102 * - kBinaryFileExtensions (below)
103 * - sExecutableExts (in nsLocalFileCommon)
104 *
105 * On Windows, the `sExecutableExts` list is used to determine whether files
106 * count as executable. For executable files, we will not offer an "open with"
107 * option when downloading, only "save as".
108 *
109 * On all platforms, the combination of these lists is used to determine
110 * whether files should be subject to application reputation checks.
111 * Specifically, all files with extensions that:
112 * - are in kBinaryFileExtensions, or
113 * - are in sExecutableExts **and not in kNonBinaryExecutables**
114 *
115 * will be subject to checks.
116 *
117 * There are tests that verify that these lists are sorted and that extensions
118 * never appear in both the sExecutableExts and kBinaryFileExtensions lists.
119 *
120 * When adding items to any lists:
121 * - please prefer adding to sExecutableExts unless it is imperative users can
122 * (potentially automatically!) open such files with a helper application
123 * without first saving them (and that outweighs any associated risk).
124 * - if adding executable items that shouldn't be submitted to apprep servers,
125 * add them to sExecutableExts and also to kNonBinaryExecutables.
126 * - always add an associated comment in the kBinaryFileExtensions list. Add
127 * a commented-out entry with an `exec` annotation if you add the actual
128 * entry in sExecutableExts.
129 *
130 * When removing items please consider whether items should still be in the
131 * sExecutableExts list even if removing them from the kBinaryFileExtensions
132 * list, and vice versa.
133 *
134 * Note that there is a GTest that does its best to check some of these
135 * invariants that you'll likely need to update if you're modifying these
136 * lists.
137 */
138
139// Items that are in sExecutableExts but shouldn't be submitted for application
140// reputation checks.
141/* static */
142const char* const ApplicationReputationService::kNonBinaryExecutables[] = {
143 // clang-format off
144 ".ad",
145 ".afploc",
146 ".air",
147 ".atloc",
148 ".ftploc",
149 ".terminal",
150 // clang-format on
151};
152
153// Items that should be submitted for application reputation checks that users
154// are able to open immediately (without first saving and then finding the
155// file). If users shouldn't be able to open them immediately, add to
156// sExecutableExts instead (see also the docstring comment above!).
157/* static */
158const char* const ApplicationReputationService::kBinaryFileExtensions[] = {
159 // Originally extracted from the "File Type Policies" Chrome extension
160 // Items listed with an `exec` comment are in the sExecutableExts list in
161 // nsLocalFileCommon.h .
162 //".001",
163 //".7z",
164 //".ace",
165 //".accda", exec // MS Access database
166 //".accdb", exec // MS Access database
167 //".accde", exec // MS Access database
168 //".accdr", exec // MS Access database
169 ".action", // Mac script
170 //".ad", exec // Windows
171 //".ade", exec // MS Access
172 //".adp", exec // MS Access
173 //".air", exec // Adobe AIR installer; excluded from apprep checks.
174 ".apk", // Android package
175 //".app", exec // Executable application
176 ".applescript",
177 //".application", exec // MS ClickOnce
178 //".appref-ms", exec // MS ClickOnce
179 //".appx", exec
180 //".appxbundle", exec
181 //".arc",
182 //".arj",
183 ".as", // Mac archive
184 //".asp", exec // Windows Server script
185 ".asx", // Windows Media Player
186 //".b64",
187 //".balz",
188 //".bas", exec // Basic script
189 ".bash", // Linux shell
190 //".bat", exec // Windows shell
191 //".bhx",
192 ".bin",
193 ".btapp", // uTorrent and Transmission
194 ".btinstall", // uTorrent and Transmission
195 ".btkey", // uTorrent and Transmission
196 ".btsearch", // uTorrent and Transmission
197 ".btskin", // uTorrent and Transmission
198 ".bz", // Linux archive (bzip)
199 ".bz2", // Linux archive (bzip2)
200 ".bzip2", // Linux archive (bzip2)
201 ".cab", // Windows archive
202 ".caction", // Automator action
203 ".cdr", // Mac disk image
204 //".cer", exec // Signed certificate file
205 ".cfg", // Windows
206 ".chi", // Windows Help
207 //".chm", exec // Windows Help
208 ".class", // Java
209 //".cmd", exec // Windows executable
210 //".com", exec // Windows executable
211 //".command", exec // Mac script
212 ".configprofile", // Configuration file for Apple systems
213 ".cpgz", // Mac archive
214 ".cpi", // Control Panel Item. Executable used for adding icons
215 // to Control Panel
216 //".cpio",
217 //".cpl", exec // Windows executable
218 //".crt", exec // Windows signed certificate
219 ".crx", // Chrome extensions
220 ".csh", // Linux shell
221 //".csv",
222 ".dart", // Mac disk image
223 ".dc42", // Apple DiskCopy Image
224 ".deb", // Linux package
225 ".definition", // Automator action
226 ".desktop", // A shortcut that runs other files
227 //".der", exec // Signed certificate
228 ".dex", // Android
229 ".dht", // HTML
230 ".dhtm", // HTML
231 ".dhtml", // HTML
232 //".diagcab", exec // Executable windows archive, like .cab
233 ".diskcopy42", // Apple DiskCopy Image
234 ".dll", // Windows executable
235 ".dmg", // Mac disk image
236 ".dmgpart", // Mac disk image
237 ".doc", // MS Office
238 ".docb", // MS Office
239 ".docm", // MS Word
240 ".docx", // MS Word
241 ".dot", // MS Word
242 ".dotm", // MS Word
243 ".dott", // MS Office
244 ".dotx", // MS Word
245 ".drv", // Windows driver
246 ".dvdr", // Mac Disk image
247 ".dylib", // Mach object dynamic library file
248 ".efi", // Firmware
249 ".eml", // MS Outlook
250 //".exe", exec // Windows executable
251 //".fat",
252 //".fileloc", exec // Apple finder internet location data file
253 ".fon", // Windows font
254 //".fxp", exec // MS FoxPro
255 ".gadget", // Windows
256 //".gif",
257 ".grp", // Windows
258 ".gz", // Linux archive (gzip)
259 ".gzip", // Linux archive (gzip)
260 ".hfs", // Mac disk image
261 //".hlp", exec // Windows Help
262 ".hqx", // Mac archive
263 //".hta", exec // HTML trusted application
264 ".htm",
265 ".html",
266 ".htt", // MS HTML template
267 //".ica",
268 ".img", // Mac disk image
269 ".imgpart", // Mac disk image
270 //".inf", exec // Windows installer
271 //".inetloc", exec // Apple finder internet location data file
272 ".ini", // Generic config file
273 //".ins", exec // IIS config
274 ".internetconnect", // Configuration file for Apple system
275 //".inx", // InstallShield
276 ".iso", // CD image
277 //".isp", exec // IIS config
278 //".isu", // InstallShield
279 //".jar", exec // Java
280#ifndef MOZ_ESR
281//".jnlp", exec // Java
282#endif
283 //".job", // Windows
284 //".jpg",
285 //".jpeg",
286 //".js", exec // JavaScript script
287 //".jse", exec // JScript
288 ".ksh", // Linux shell
289 //".lha",
290 //".library-ms", exec // Windows
291 //".lnk", exec // Windows
292 ".local", // Windows
293 //".lpaq1",
294 //".lpaq5",
295 //".lpaq8",
296 //".lzh",
297 //".lzma",
298 //".mad", exec // MS Access
299 //".maf", exec // MS Access
300 //".mag", exec // MS Access
301 //".mam", exec // MS Access
302 ".manifest", // Windows
303 //".maq", exec // MS Access
304 //".mar", exec // MS Access
305 //".mas", exec // MS Access
306 //".mat", exec // MS Access
307 //".mau", exec // Media attachment
308 //".mav", exec // MS Access
309 //".maw", exec // MS Access
310 //".mda", exec // MS Access
311 //".mdb", exec // MS Access
312 //".mde", exec // MS Access
313 //".mdt", exec // MS Access
314 //".mdw", exec // MS Access
315 //".mdz", exec // MS Access
316 ".mht", // MS HTML
317 ".mhtml", // MS HTML
318 ".mim", // MS Mail
319 //".mkv",
320 ".mmc", // MS Office
321 ".mobileconfig", // Configuration file for Apple systems
322 ".mof", // Windows
323 //".mov",
324 //".mp3",
325 //".mp4",
326 ".mpkg", // Mac installer
327 //".msc", exec // Windows executable
328 ".msg", // MS Outlook
329 //".msh", exec // Windows shell
330 //".msh1", exec // Windows shell
331 //".msh1xml", exec // Windows shell
332 //".msh2", exec // Windows shell
333 //".msh2xml", exec // Windows shell
334 //".mshxml", exec // Windows
335 //".msi", exec // Windows installer
336 //".msix", exec // Windows installer
337 //".msixbundle", exec // Windows installer
338 //".msp", exec // Windows installer
339 //".mst", exec // Windows installer
340 ".ndif", // Mac disk image
341 ".networkconnect", // Configuration file for Apple systems
342 //".ntfs", // 7z
343 ".ocx", // ActiveX
344 //".ops", exec // MS Office
345 ".osas", // AppleScript
346 ".osax", // AppleScript
347 //".out", // Linux binary
348 ".oxt", // OpenOffice extension, can execute arbitrary code
349 //".package",
350 //".paf", // PortableApps package
351 //".paq8f",
352 //".paq8jd",
353 //".paq8l",
354 //".paq8o",
355 ".partial", // Downloads
356 ".pax", // Mac archive
357 //".pcd", exec // Microsoft Visual Test
358 ".pdf", // Adobe Acrobat
359 //".pea",
360 ".pet", // Linux package
361 //".pif", exec // Windows
362 ".pkg", // Mac installer
363 ".pl", // Perl script
364 //".plg", exec // MS Visual Studio
365 //".png",
366 ".pot", // MS PowerPoint
367 ".potm", // MS PowerPoint
368 ".potx", // MS PowerPoint
369 ".ppam", // MS PowerPoint
370 ".pps", // MS PowerPoint
371 ".ppsm", // MS PowerPoint
372 ".ppsx", // MS PowerPoint
373 ".ppt", // MS PowerPoint
374 ".pptm", // MS PowerPoint
375 ".pptx", // MS PowerPoint
376 //".prf", exec // MS Outlook
377 //".prg", exec // Windows
378 ".ps1", // Windows shell
379 ".ps1xml", // Windows shell
380 ".ps2", // Windows shell
381 ".ps2xml", // Windows shell
382 ".psc1", // Windows shell
383 ".psc2", // Windows shell
384 //".pst", exec // MS Outlook
385 ".pup", // Linux package
386 ".py", // Python script
387 ".pyc", // Python binary
388 ".pyd", // Equivalent of a DLL, for python libraries
389 ".pyo", // Compiled python code
390 ".pyw", // Python GUI
391 //".quad",
392 //".r00",
393 //".r01",
394 //".r02",
395 //".r03",
396 //".r04",
397 //".r05",
398 //".r06",
399 //".r07",
400 //".r08",
401 //".r09",
402 //".r10",
403 //".r11",
404 //".r12",
405 //".r13",
406 //".r14",
407 //".r15",
408 //".r16",
409 //".r17",
410 //".r18",
411 //".r19",
412 //".r20",
413 //".r21",
414 //".r22",
415 //".r23",
416 //".r24",
417 //".r25",
418 //".r26",
419 //".r27",
420 //".r28",
421 //".r29",
422 //".rar",
423 ".rb", // Ruby script
424 //".reg", exec // Windows Registry
425 ".rels", // MS Office
426 //".rgs", // Windows Registry
427 ".rpm", // Linux package
428 ".rtf", // MS Office
429 //".run", // Linux shell
430 //".scf", exec // Windows shell
431 ".scpt", // AppleScript
432 ".scptd", // AppleScript
433 //".scr", exec // Windows
434 //".sct", exec // Windows shell
435 //".search-ms", exec // Windows Saved Search
436 ".seplugin", // AppleScript
437 ".service", // Systemd service unit file
438 //".settingcontent-ms", exec // Windows settings
439 ".sh", // Linux shell
440 ".shar", // Linux shell
441 //".shb", exec // Windows
442 //".shs", exec // Windows shell
443 ".sht", // HTML
444 ".shtm", // HTML
445 ".shtml", // HTML
446 ".sldm", // MS PowerPoint
447 ".sldx", // MS PowerPoint
448 ".slk", // MS Excel
449 ".slp", // Linux package
450 ".smi", // Mac disk image
451 ".sparsebundle", // Mac disk image
452 ".sparseimage", // Mac disk image
453 ".spl", // Adobe Flash
454 //".squashfs",
455 ".svg",
456 ".swf", // Adobe Flash
457 ".swm", // Windows Imaging
458 ".sys", // Windows
459 ".tar", // Linux archive
460 ".taz", // Linux archive (bzip2)
461 ".tbz", // Linux archive (bzip2)
462 ".tbz2", // Linux archive (bzip2)
463 ".tcsh", // Linux shell
464 //".tif",
465 ".tgz", // Linux archive (gzip)
466 //".toast", // Roxio disk image
467 ".torrent", // Bittorrent
468 ".tpz", // Linux archive (gzip)
469 //".txt",
470 ".txz", // Linux archive (xz)
471 ".tz", // Linux archive (gzip)
472 //".u3p", // U3 Smart Apps
473 ".udf", // MS Excel
474 ".udif", // Mac disk image
475 //".url", exec // Windows
476 //".uu",
477 //".uue",
478 //".vb", exec // Visual Basic script
479 //".vbe", exec // Visual Basic script
480 //".vbs", exec // Visual Basic script
481 //".vbscript", // Visual Basic script
482 //".vdx", exec // MS Visio
483 ".vhd", // Windows virtual hard drive
484 ".vhdx", // Windows virtual hard drive
485 ".vmdk", // VMware virtual disk
486 //".vsd", exec // MS Visio
487 //".vsdm", exec // MS Visio
488 //".vsdx", exec // MS Visio
489 //".vsmacros", exec // MS Visual Studio
490 //".vss", exec // MS Visio
491 //".vssm", exec // MS Visio
492 //".vssx", exec // MS Visio
493 //".vst", exec // MS Visio
494 //".vstm", exec // MS Visio
495 //".vstx", exec // MS Visio
496 //".vsw", exec // MS Visio
497 //".vsx", exec // MS Visio
498 //".vtx", exec // MS Visio
499 //".wav",
500 //".webloc", // MacOS website location file
501 //".webp",
502 ".website", // Windows
503 ".wflow", // Automator action
504 ".wim", // Windows Imaging
505 ".workflow", // Mac Automator
506 //".wrc", // FreeArc archive
507 //".ws", exec // Windows script
508 ".wsb", // Windows Sandbox configuration
509 //".wsc", exec // Windows script
510 //".wsf", exec // Windows script
511 //".wsh", exec // Windows script
512 ".xar", // MS Excel
513 ".xbap", // XAML Browser Application
514 ".xht",
515 ".xhtm",
516 ".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
546static 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
558static 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
568enum 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
594using Reason = mozilla::glean::application_reputation::ReasonLabel;
595
596class 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.
602class 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_v
<decltype(this), nsINamed*>, "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.
759class 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
789NS_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" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 789); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__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" ")"
, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 789); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingDBLookup\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__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" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 789); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__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" ")"
, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 789); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingDBLookup\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__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"
, "./../../../../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(std::size(table) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
790
791PendingDBLookup::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
796PendingDBLookup::~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
801nsresult PendingDBLookup::LookupSpec(const nsACString& aSpec,
802 const LookupType& aLookupType) {
803 LOG(("Checking principal %s [this=%p]", PromiseFlatCString(aSpec).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, "Checking principal %s [this=%p]"
, TPromiseFlatString<char>(aSpec).get(), this); } } while
(0)
804 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]"
, TPromiseFlatString<char>(aSpec).get(), this); } } while
(0)
;
805 mSpec = aSpec;
806 mLookupType = aLookupType;
807 nsresult rv = LookupSpecInternal(aSpec);
808 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
809 nsAutoCString errorName;
810 mozilla::GetErrorName(rv, errorName);
811 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)
812 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)
;
813 return mPendingLookup->LookupNext(); // ignore this lookup and move to next
814 }
815 // LookupSpecInternal has called nsIUrlClassifierCallback.lookup, which is
816 // guaranteed to call HandleEvent.
817 return rv;
818}
819
820nsresult PendingDBLookup::LookupSpecInternal(const nsACString& aSpec) {
821 nsresult rv;
822
823 nsCOMPtr<nsIURI> uri;
824 nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID"@mozilla.org/network/io-service;1", &rv);
825 rv = ios->NewURI(aSpec, nullptr, nullptr, getter_AddRefs(uri));
826 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 826); return rv; } } while (false)
;
827
828 OriginAttributes attrs;
829 nsCOMPtr<nsIPrincipal> principal =
830 BasePrincipal::CreateContentPrincipal(uri, attrs);
831 if (!principal) {
832 return NS_ERROR_FAILURE;
833 }
834
835 // Check local lists to see if the URI has already been whitelisted or
836 // blacklisted.
837 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)
;
838 nsCOMPtr<nsIUrlClassifierDBService> dbService =
839 mozilla::components::UrlClassifierDB::Service(&rv);
840 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 840); return rv; } } while (false)
;
841
842 nsAutoCString tables;
843 nsAutoCString allowlist;
844 Preferences::GetCString(PREF_DOWNLOAD_ALLOW_TABLE"urlclassifier.downloadAllowTable", allowlist);
845 if ((mLookupType != LookupType::BlocklistOnly) && !allowlist.IsEmpty()) {
846 tables.Append(allowlist);
847 }
848 nsAutoCString blocklist;
849 Preferences::GetCString(PREF_DOWNLOAD_BLOCK_TABLE"urlclassifier.downloadBlockTable", blocklist);
850 if ((mLookupType != LookupType::AllowlistOnly) && !blocklist.IsEmpty()) {
851 if (!tables.IsEmpty()) {
852 tables.Append(',');
853 }
854 tables.Append(blocklist);
855 }
856 if (principal->IsSystemPrincipal()) {
857 return mPendingLookup->LookupNext();
858 }
859 return dbService->Lookup(principal, tables, this);
860}
861
862NS_IMETHODIMPnsresult
863PendingDBLookup::HandleEvent(const nsACString& tables) {
864 // HandleEvent is guaranteed to call either:
865 // 1) PendingLookup::OnComplete if the URL matches the blocklist, or
866 // 2) PendingLookup::LookupNext if the URL does not match the blocklist.
867 // Blocklisting trumps allowlisting.
868 nsAutoCString blockList;
869 Preferences::GetCString(PREF_DOWNLOAD_BLOCK_TABLE"urlclassifier.downloadBlockTable", blockList);
870 if ((mLookupType != LookupType::AllowlistOnly) && !blockList.IsEmpty() &&
871 FindInReadable(blockList, tables)) {
872 mPendingLookup->mBlocklistCount++;
873 mozilla::glean::application_reputation::local.AccumulateSingleSample(
874 BLOCK_LIST);
875 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)
;
876 return mPendingLookup->OnComplete(
877 nsIApplicationReputationService::VERDICT_DANGEROUS,
878 Reason::eLocalblocklist, NS_OK);
879 }
880
881 nsAutoCString allowList;
882 Preferences::GetCString(PREF_DOWNLOAD_ALLOW_TABLE"urlclassifier.downloadAllowTable", allowList);
883 if ((mLookupType != LookupType::BlocklistOnly) && !allowList.IsEmpty() &&
884 FindInReadable(allowList, tables)) {
885 mPendingLookup->mAllowlistCount++;
886 mozilla::glean::application_reputation::local.AccumulateSingleSample(
887 ALLOW_LIST);
888 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)
;
889 // Don't call onComplete, since blocklisting trumps allowlisting
890 return mPendingLookup->LookupNext();
891 }
892
893 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)
;
894 mozilla::glean::application_reputation::local.AccumulateSingleSample(NO_LIST);
895 return mPendingLookup->LookupNext();
896}
897
898NS_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" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 900
); __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" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 900); __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" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 900
); __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" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 900); __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", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 900); 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(std::size(table) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
899 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" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 900
); __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" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 900); __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" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 900
); __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" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 900); __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", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 900); 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(std::size(table) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
900 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" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 900
); __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" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 900); __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" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 900
); __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" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 900); __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", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 900); 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(std::size(table) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
901
902PendingLookup::PendingLookup(nsIApplicationReputationQuery* aQuery,
903 nsIApplicationReputationCallback* aCallback)
904 : mIsBinaryFile(false),
905 mBlocklistCount(0),
906 mAllowlistCount(0),
907 mQuery(aQuery),
908 mCallback(aCallback) {
909 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)
;
910}
911
912PendingLookup::~PendingLookup() {
913 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)
;
914}
915
916static const char* const kDmgFileExtensions[] = {
917 ".cdr", ".dart", ".dc42", ".diskcopy42",
918 ".dmg", ".dmgpart", ".dvdr", ".img",
919 ".imgpart", ".iso", ".ndif", ".smi",
920 ".sparsebundle", ".sparseimage", ".toast", ".udif",
921};
922
923static const char* const kRarFileExtensions[] = {
924 ".r00", ".r01", ".r02", ".r03", ".r04", ".r05", ".r06", ".r07",
925 ".r08", ".r09", ".r10", ".r11", ".r12", ".r13", ".r14", ".r15",
926 ".r16", ".r17", ".r18", ".r19", ".r20", ".r21", ".r22", ".r23",
927 ".r24", ".r25", ".r26", ".r27", ".r28", ".r29", ".rar",
928};
929
930static const char* const kZipFileExtensions[] = {
931 ".zip", // Generic archive
932 ".zipx", // WinZip
933};
934
935static const char* GetFileExt(const nsACString& aFilename,
936 const char* const aFileExtensions[],
937 const size_t aLength) {
938 for (size_t i = 0; i < aLength; ++i) {
939 if (StringEndsWith(aFilename, nsDependentCString(aFileExtensions[i]),
940 nsCaseInsensitiveCStringComparator)) {
941 return aFileExtensions[i];
942 }
943 }
944 return nullptr;
945}
946
947static const char* GetFileExt(const nsACString& aFilename) {
948#define _GetFileExt(_f, _l)GetFileExt(_f, _l, std::size(_l)) GetFileExt(_f, _l, std::size(_l))
949 const char* ext = _GetFileExt(GetFileExt(aFilename, ApplicationReputationService::kBinaryFileExtensions
, std::size(ApplicationReputationService::kBinaryFileExtensions
))
950 aFilename, ApplicationReputationService::kBinaryFileExtensions)GetFileExt(aFilename, ApplicationReputationService::kBinaryFileExtensions
, std::size(ApplicationReputationService::kBinaryFileExtensions
))
;
951 if (ext == nullptr &&
952 !_GetFileExt(aFilename,GetFileExt(aFilename, ApplicationReputationService::kNonBinaryExecutables
, std::size(ApplicationReputationService::kNonBinaryExecutables
))
953 ApplicationReputationService::kNonBinaryExecutables)GetFileExt(aFilename, ApplicationReputationService::kNonBinaryExecutables
, std::size(ApplicationReputationService::kNonBinaryExecutables
))
) {
954 ext = _GetFileExt(aFilename, sExecutableExts)GetFileExt(aFilename, sExecutableExts, std::size(sExecutableExts
))
;
955 }
956 return ext;
957}
958
959// Returns true if the file extension matches one in the given array.
960static bool IsFileType(const nsACString& aFilename,
961 const char* const aFileExtensions[],
962 const size_t aLength) {
963 return GetFileExt(aFilename, aFileExtensions, aLength) != nullptr;
964}
965
966static bool IsBinary(const nsACString& aFilename) {
967 return IsFileType(
968 aFilename, ApplicationReputationService::kBinaryFileExtensions,
969 std::size(ApplicationReputationService::kBinaryFileExtensions)) ||
970 (!IsFileType(
971 aFilename, ApplicationReputationService::kNonBinaryExecutables,
972 std::size(ApplicationReputationService::kNonBinaryExecutables)) &&
973 IsFileType(aFilename, sExecutableExts, std::size(sExecutableExts)));
974}
975
976ClientDownloadRequest::DownloadType PendingLookup::GetDownloadType(
977 const nsACString& aFilename) {
978 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)"
, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 978); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsBinary(aFilename)"
")"); do { MOZ_CrashSequence(__null, 978); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
979
980 // Extensions are matched case-insensitively, so compare against a lowercased
981 // copy of the filename.
982 nsAutoCString fileName(aFilename);
983 ToLowerCase(fileName);
984
985 // From
986 // https://cs.chromium.org/chromium/src/chrome/common/safe_browsing/download_protection_util.cc?l=17
987 if (StringEndsWith(fileName, ".zip"_ns)) {
988 return ClientDownloadRequest::ZIPPED_EXECUTABLE;
989 } else if (StringEndsWith(fileName, ".apk"_ns)) {
990 return ClientDownloadRequest::ANDROID_APK;
991 } else if (StringEndsWith(fileName, ".app"_ns) ||
992 StringEndsWith(fileName, ".applescript"_ns) ||
993 StringEndsWith(fileName, ".cdr"_ns) ||
994 StringEndsWith(fileName, ".dart"_ns) ||
995 StringEndsWith(fileName, ".dc42"_ns) ||
996 StringEndsWith(fileName, ".diskcopy42"_ns) ||
997 StringEndsWith(fileName, ".dmg"_ns) ||
998 StringEndsWith(fileName, ".dmgpart"_ns) ||
999 StringEndsWith(fileName, ".dvdr"_ns) ||
1000 StringEndsWith(fileName, ".img"_ns) ||
1001 StringEndsWith(fileName, ".imgpart"_ns) ||
1002 StringEndsWith(fileName, ".iso"_ns) ||
1003 StringEndsWith(fileName, ".mpkg"_ns) ||
1004 StringEndsWith(fileName, ".ndif"_ns) ||
1005 StringEndsWith(fileName, ".osas"_ns) ||
1006 StringEndsWith(fileName, ".osax"_ns) ||
1007 StringEndsWith(fileName, ".pkg"_ns) ||
1008 StringEndsWith(fileName, ".scpt"_ns) ||
1009 StringEndsWith(fileName, ".scptd"_ns) ||
1010 StringEndsWith(fileName, ".seplugin"_ns) ||
1011 StringEndsWith(fileName, ".smi"_ns) ||
1012 StringEndsWith(fileName, ".sparsebundle"_ns) ||
1013 StringEndsWith(fileName, ".sparseimage"_ns) ||
1014 StringEndsWith(fileName, ".toast"_ns) ||
1015 StringEndsWith(fileName, ".udif"_ns)) {
1016 return ClientDownloadRequest::MAC_EXECUTABLE;
1017 }
1018
1019 return ClientDownloadRequest::WIN_EXECUTABLE; // default to Windows binaries
1020}
1021
1022nsresult PendingLookup::LookupNext() {
1023 // We must call LookupNext or SendRemoteQuery upon return.
1024 // Look up all of the URLs that could allow or block this download.
1025 // Blocklist first.
1026
1027 // If a url is in blocklist we should call PendingLookup::OnComplete directly.
1028 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"
, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1028); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mBlocklistCount == 0"
")"); do { MOZ_CrashSequence(__null, 1028); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1029
1030 nsCString spec;
1031 if (!mAnylistSpecs.IsEmpty()) {
1032 // Check the source URI only.
1033 spec = mAnylistSpecs.PopLastElement();
1034 RefPtr<PendingDBLookup> lookup(new PendingDBLookup(this));
1035
1036 // We don't need to check whitelist if the file is not a binary file.
1037 auto type =
1038 mIsBinaryFile ? LookupType::BothLists : LookupType::BlocklistOnly;
1039 return lookup->LookupSpec(spec, type);
1040 }
1041
1042 if (!mBlocklistSpecs.IsEmpty()) {
1043 // Check the referrer and redirect chain.
1044 spec = mBlocklistSpecs.PopLastElement();
1045 RefPtr<PendingDBLookup> lookup(new PendingDBLookup(this));
1046 return lookup->LookupSpec(spec, LookupType::BlocklistOnly);
1047 }
1048
1049 // Now that we've looked up all of the URIs against the blocklist,
1050 // if any of mAnylistSpecs or mAllowlistSpecs matched the allowlist,
1051 // go ahead and pass.
1052 if (mAllowlistCount > 0) {
1053 return OnComplete(nsIApplicationReputationService::VERDICT_SAFE,
1054 Reason::eLocalwhitelist, NS_OK);
1055 }
1056
1057 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"
, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1057); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAllowlistSpecs.Length() == 0"
")"); do { MOZ_CrashSequence(__null, 1057); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1058
1059 // Only binary signatures remain.
1060 if (!mAllowlistSpecs.IsEmpty()) {
1061 spec = mAllowlistSpecs.PopLastElement();
1062 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)
;
1063 RefPtr<PendingDBLookup> lookup(new PendingDBLookup(this));
1064 return lookup->LookupSpec(spec, LookupType::AllowlistOnly);
1065 }
1066
1067 if (!mFileName.IsEmpty()) {
1068 if (IsBinary(mFileName)) {
1069 mozilla::glean::application_reputation::binary_type
1070 .EnumGet(mozilla::glean::application_reputation::BinaryTypeLabel::
1071 eBinaryfile)
1072 .Add();
1073 } else if (IsFileType(mFileName, kSafeFileExtensions,
1074 std::size(kSafeFileExtensions))) {
1075 mozilla::glean::application_reputation::binary_type
1076 .EnumGet(mozilla::glean::application_reputation::BinaryTypeLabel::
1077 eNonbinaryfile)
1078 .Add();
1079 } else if (IsFileType(mFileName, kMozNonBinaryExecutables,
1080 std::size(kMozNonBinaryExecutables))) {
1081 mozilla::glean::application_reputation::binary_type
1082 .EnumGet(mozilla::glean::application_reputation::BinaryTypeLabel::
1083 eMoznonbinaryfile)
1084 .Add();
1085 } else {
1086 mozilla::glean::application_reputation::binary_type
1087 .EnumGet(mozilla::glean::application_reputation::BinaryTypeLabel::
1088 eUnknownfile)
1089 .Add();
1090 }
1091 } else {
1092 mozilla::glean::application_reputation::binary_type
1093 .EnumGet(mozilla::glean::application_reputation::BinaryTypeLabel::
1094 eMissingfilename)
1095 .Add();
1096 }
1097
1098 if (IsFileType(mFileName, kDmgFileExtensions,
1099 std::size(kDmgFileExtensions))) {
1100 mozilla::glean::application_reputation::binary_archive
1101 .EnumGet(mozilla::glean::application_reputation::BinaryArchiveLabel::
1102 eDmgfile)
1103 .Add();
1104 } else if (IsFileType(mFileName, kRarFileExtensions,
1105 std::size(kRarFileExtensions))) {
1106 mozilla::glean::application_reputation::binary_archive
1107 .EnumGet(mozilla::glean::application_reputation::BinaryArchiveLabel::
1108 eRarfile)
1109 .Add();
1110 } else if (IsFileType(mFileName, kZipFileExtensions,
1111 std::size(kZipFileExtensions))) {
1112 mozilla::glean::application_reputation::binary_archive
1113 .EnumGet(mozilla::glean::application_reputation::BinaryArchiveLabel::
1114 eZipfile)
1115 .Add();
1116 } else if (mIsBinaryFile) {
1117 mozilla::glean::application_reputation::binary_archive
1118 .EnumGet(mozilla::glean::application_reputation::BinaryArchiveLabel::
1119 eOtherbinaryfile)
1120 .Add();
1121 }
1122
1123 // There are no more URIs to check against local list. If the file is
1124 // not eligible for remote lookup, bail.
1125 if (!mIsBinaryFile) {
1126 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)
;
1127 return OnComplete(nsIApplicationReputationService::VERDICT_SAFE,
1128 Reason::eNonbinaryfile, NS_OK);
1129 }
1130
1131 nsresult rv = SendRemoteQuery();
1132 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1133 return OnComplete(nsIApplicationReputationService::VERDICT_SAFE,
1134 Reason::eInternalerror, rv);
1135 }
1136 return NS_OK;
1137}
1138
1139nsCString PendingLookup::EscapeCertificateAttribute(
1140 const nsACString& aAttribute) {
1141 // Escape '/' because it's a field separator, and '%' because Chrome does
1142 nsCString escaped;
1143 escaped.SetCapacity(aAttribute.Length());
1144 for (unsigned int i = 0; i < aAttribute.Length(); ++i) {
1145 if (aAttribute.Data()[i] == '%') {
1146 escaped.AppendLiteral("%25");
1147 } else if (aAttribute.Data()[i] == '/') {
1148 escaped.AppendLiteral("%2F");
1149 } else if (aAttribute.Data()[i] == ' ') {
1150 escaped.AppendLiteral("%20");
1151 } else {
1152 escaped.Append(aAttribute.Data()[i]);
1153 }
1154 }
1155 return escaped;
1156}
1157
1158nsCString PendingLookup::EscapeFingerprint(const nsACString& aFingerprint) {
1159 // Google's fingerprint doesn't have colons
1160 nsCString escaped;
1161 escaped.SetCapacity(aFingerprint.Length());
1162 for (unsigned int i = 0; i < aFingerprint.Length(); ++i) {
1163 if (aFingerprint.Data()[i] != ':') {
1164 escaped.Append(aFingerprint.Data()[i]);
1165 }
1166 }
1167 return escaped;
1168}
1169
1170nsresult PendingLookup::GenerateWhitelistStringsForPair(
1171 nsIX509Cert* certificate, nsIX509Cert* issuer) {
1172 // The whitelist paths have format:
1173 // http://sb-ssl.google.com/safebrowsing/csd/certificate/<issuer_cert_fingerprint>[/CN=<cn>][/O=<org>][/OU=<unit>]
1174 // Any of CN, O, or OU may be omitted from the whitelist entry. Unfortunately
1175 // this is not publicly documented, but the Chrome implementation can be found
1176 // here:
1177 // https://code.google.com/p/chromium/codesearch#search/&q=GetCertificateWhitelistStrings
1178 nsCString whitelistString(
1179 "http://sb-ssl.google.com/safebrowsing/csd/certificate/");
1180
1181 nsString fingerprint;
1182 nsresult rv = issuer->GetSha1Fingerprint(fingerprint);
1183 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1183); return rv; } } while (false)
;
1184 whitelistString.Append(EscapeFingerprint(NS_ConvertUTF16toUTF8(fingerprint)));
1185
1186 nsString commonName;
1187 rv = certificate->GetCommonName(commonName);
1188 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1188); return rv; } } while (false)
;
1189 if (!commonName.IsEmpty()) {
1190 whitelistString.AppendLiteral("/CN=");
1191 whitelistString.Append(
1192 EscapeCertificateAttribute(NS_ConvertUTF16toUTF8(commonName)));
1193 }
1194
1195 nsString organization;
1196 rv = certificate->GetOrganization(organization);
1197 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1197); return rv; } } while (false)
;
1198 if (!organization.IsEmpty()) {
1199 whitelistString.AppendLiteral("/O=");
1200 whitelistString.Append(
1201 EscapeCertificateAttribute(NS_ConvertUTF16toUTF8(organization)));
1202 }
1203
1204 nsString organizationalUnit;
1205 rv = certificate->GetOrganizationalUnit(organizationalUnit);
1206 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1206); return rv; } } while (false)
;
1207 if (!organizationalUnit.IsEmpty()) {
1208 whitelistString.AppendLiteral("/OU=");
1209 whitelistString.Append(
1210 EscapeCertificateAttribute(NS_ConvertUTF16toUTF8(organizationalUnit)));
1211 }
1212 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)
;
1213
1214 mAllowlistSpecs.AppendElement(whitelistString);
1215 return NS_OK;
1216}
1217
1218nsresult PendingLookup::GenerateWhitelistStringsForChain(
1219 const safe_browsing::ClientDownloadRequest_CertificateChain& aChain) {
1220 // We need a signing certificate and an issuer to construct a whitelist
1221 // entry.
1222 if (aChain.element_size() < 2) {
1223 return NS_OK;
1224 }
1225
1226 // Get the signer.
1227 nsresult rv;
1228 nsCOMPtr<nsIX509CertDB> certDB = do_GetService(NS_X509CERTDB_CONTRACTID"@mozilla.org/security/x509certdb;1", &rv);
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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1229); return rv; } } while (false)
;
1230
1231 nsCOMPtr<nsIX509Cert> signer;
1232 nsTArray<uint8_t> signerBytes;
1233 signerBytes.AppendElements(aChain.element(0).certificate().data(),
1234 aChain.element(0).certificate().size());
1235 rv = certDB->ConstructX509(signerBytes, getter_AddRefs(signer));
1236 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1236); return rv; } } while (false)
;
1237
1238 for (int i = 1; i < aChain.element_size(); ++i) {
1239 // Get the issuer.
1240 nsCOMPtr<nsIX509Cert> issuer;
1241 nsTArray<uint8_t> issuerBytes;
1242 issuerBytes.AppendElements(aChain.element(i).certificate().data(),
1243 aChain.element(i).certificate().size());
1244 rv = certDB->ConstructX509(issuerBytes, getter_AddRefs(issuer));
1245 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1245); return rv; } } while (false)
;
1246
1247 rv = GenerateWhitelistStringsForPair(signer, issuer);
1248 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1248); return rv; } } while (false)
;
1249 }
1250 return NS_OK;
1251}
1252
1253nsresult PendingLookup::GenerateWhitelistStrings() {
1254 for (int i = 0; i < mRequest.signature().certificate_chain_size(); ++i) {
1255 nsresult rv = GenerateWhitelistStringsForChain(
1256 mRequest.signature().certificate_chain(i));
1257 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1257); return rv; } } while (false)
;
1258 }
1259 return NS_OK;
1260}
1261
1262nsresult PendingLookup::AddRedirects(nsIArray* aRedirects) {
1263 uint32_t length = 0;
1264 aRedirects->GetLength(&length);
1265 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)
;
1266 nsCOMPtr<nsISimpleEnumerator> iter;
1267 nsresult rv = aRedirects->Enumerate(getter_AddRefs(iter));
1268 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1268); return rv; } } while (false)
;
1269
1270 bool hasMoreRedirects = false;
1271 rv = iter->HasMoreElements(&hasMoreRedirects);
1272 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1272); return rv; } } while (false)
;
1273
1274 while (hasMoreRedirects) {
1275 nsCOMPtr<nsISupports> supports;
1276 rv = iter->GetNext(getter_AddRefs(supports));
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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1277); return rv; } } while (false)
;
1278
1279 nsCOMPtr<nsIRedirectHistoryEntry> redirectEntry =
1280 do_QueryInterface(supports, &rv);
1281 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1281); return rv; } } while (false)
;
1282
1283 nsCOMPtr<nsIPrincipal> principal;
1284 rv = redirectEntry->GetPrincipal(getter_AddRefs(principal));
1285 auto* basePrin = BasePrincipal::Cast(principal);
1286 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1286); return rv; } } while (false)
;
1287
1288 nsCOMPtr<nsIURI> uri;
1289 rv = basePrin->GetURI(getter_AddRefs(uri));
1290 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1290); return rv; } } while (false)
;
1291
1292 // Add the spec to our list of local lookups. The most recent redirect is
1293 // the last element.
1294 nsCString spec;
1295 rv = GetStrippedSpec(uri, spec);
1296 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1296); return rv; } } while (false)
;
1297 mBlocklistSpecs.AppendElement(spec);
1298 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)
;
1299
1300 // Store the redirect information in the remote request.
1301 ClientDownloadRequest_Resource* resource = mRequest.add_resources();
1302 resource->set_url(spec.get());
1303 resource->set_type(ClientDownloadRequest::DOWNLOAD_REDIRECT);
1304
1305 rv = iter->HasMoreElements(&hasMoreRedirects);
1306 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1306); return rv; } } while (false)
;
1307 }
1308 return NS_OK;
1309}
1310
1311nsresult PendingLookup::StartLookup() {
1312 mStartTime = TimeStamp::Now();
1313 nsresult rv = DoLookupInternal();
1314 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1315 return OnComplete(nsIApplicationReputationService::VERDICT_SAFE,
1316 Reason::eInternalerror, NS_OK);
1317 }
1318 return rv;
1319}
1320
1321nsresult PendingLookup::GetSpecHash(nsACString& aSpec,
1322 nsACString& hexEncodedHash) {
1323 nsCOMPtr<nsICryptoHash> cryptoHash;
1324 nsresult rv =
1325 NS_NewCryptoHash(nsICryptoHash::SHA256, getter_AddRefs(cryptoHash));
1326 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1326); return rv; } } while (false)
;
1327
1328 rv = cryptoHash->Update(
1329 reinterpret_cast<const uint8_t*>(aSpec.BeginReading()), aSpec.Length());
1330 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1330); return rv; } } while (false)
;
1331
1332 nsAutoCString binaryHash;
1333 rv = cryptoHash->Finish(false, binaryHash);
1334 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1334); return rv; } } while (false)
;
1335
1336 // This needs to match HexEncode() in Chrome's
1337 // src/base/strings/string_number_conversions.cc
1338 static const char* const hex = "0123456789ABCDEF";
1339 hexEncodedHash.SetCapacity(2 * binaryHash.Length());
1340 for (size_t i = 0; i < binaryHash.Length(); ++i) {
1341 auto c = static_cast<unsigned char>(binaryHash[i]);
1342 hexEncodedHash.Append(hex[(c >> 4) & 0x0F]);
1343 hexEncodedHash.Append(hex[c & 0x0F]);
1344 }
1345
1346 return NS_OK;
1347}
1348
1349nsresult PendingLookup::GetStrippedSpec(nsIURI* aUri, nsACString& escaped) {
1350 if (NS_WARN_IF(!aUri)NS_warn_if_impl(!aUri, "!aUri", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1350)
) {
1351 return NS_ERROR_INVALID_ARG;
1352 }
1353
1354 nsresult rv;
1355 rv = aUri->GetScheme(escaped);
1356 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1356); return rv; } } while (false)
;
1357
1358 if (escaped.EqualsLiteral("blob")) {
1359 aUri->GetSpec(escaped);
1360 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)
1361 ("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)
1362 "[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)
1363 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)
;
1364 return NS_OK;
1365 }
1366
1367 if (escaped.EqualsLiteral("data")) {
1368 // Replace URI with "data:<everything before comma>,SHA256(<whole URI>)"
1369 aUri->GetSpec(escaped);
1370 int32_t comma = escaped.FindChar(',');
1371 if (comma > -1 &&
1372 static_cast<nsCString::size_type>(comma) < escaped.Length() - 1) {
1373 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:'" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1373); AnnotateMozCrashReason("MOZ_ASSERT" "(" "comma > 4"
") (" "Data URIs start with 'data:'" ")"); do { MOZ_CrashSequence
(__null, 1373); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1374 nsAutoCString hexEncodedHash;
1375 rv = GetSpecHash(escaped, hexEncodedHash);
1376 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
1377 escaped.Truncate(comma + 1);
1378 escaped.Append(hexEncodedHash);
1379 }
1380 }
1381
1382 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)
1383 ("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)
1384 "%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)
1385 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)
;
1386 return NS_OK;
1387 }
1388
1389 // If aURI is not an nsIURL, we do not want to check the lists or send a
1390 // remote query.
1391 nsCOMPtr<nsIURL> url = do_QueryInterface(aUri, &rv);
1392 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1393 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)
1394 ("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)
1395 "= %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)
1396 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)
;
1397 return rv;
1398 }
1399
1400 nsCString temp;
1401 rv = url->GetHostPort(temp);
1402 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1402); return rv; } } while (false)
;
1403
1404 escaped.AppendLiteral("://");
1405 escaped.Append(temp);
1406
1407 rv = url->GetFilePath(temp);
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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1408); return rv; } } while (false)
;
1409
1410 // nsIUrl.filePath starts with '/'
1411 escaped.Append(temp);
1412
1413 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)
1414 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)
;
1415 return NS_OK;
1416}
1417
1418nsresult PendingLookup::DoLookupInternal() {
1419 // We want to check the target URI, its referrer, and associated redirects
1420 // against the local lists.
1421 nsCOMPtr<nsIURI> uri;
1422 nsresult rv = mQuery->GetSourceURI(getter_AddRefs(uri));
1423 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1423); return rv; } } while (false)
;
1424
1425 nsCString sourceSpec;
1426 rv = GetStrippedSpec(uri, sourceSpec);
1427 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1427); return rv; } } while (false)
;
1428
1429 mAnylistSpecs.AppendElement(sourceSpec);
1430
1431 ClientDownloadRequest_Resource* resource = mRequest.add_resources();
1432 resource->set_url(sourceSpec.get());
1433 resource->set_type(ClientDownloadRequest::DOWNLOAD_URL);
1434
1435 nsCOMPtr<nsIReferrerInfo> referrerInfo;
1436 (void)mQuery->GetReferrerInfo(getter_AddRefs(referrerInfo));
1437 nsCOMPtr<nsIURI> referrer;
1438 // It is quite possible that referrer header is omitted due to security reason
1439 // (for example navigation from https-> http). Hence we should use the
1440 // original referrer which has not applied referrer policy yet, to make sure
1441 // we don't mistakenly allow unsafe download.
1442 if (referrerInfo) {
1443 referrer = referrerInfo->GetOriginalReferrer();
1444 }
1445
1446 if (referrer) {
1447 nsCString referrerSpec;
1448 rv = GetStrippedSpec(referrer, referrerSpec);
1449 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1449); return rv; } } while (false)
;
1450 mBlocklistSpecs.AppendElement(referrerSpec);
1451 resource->set_referrer(referrerSpec.get());
1452 }
1453
1454 nsCOMPtr<nsIArray> redirects;
1455 rv = mQuery->GetRedirects(getter_AddRefs(redirects));
Value stored to 'rv' is never read
1456 if (redirects) {
1457 AddRedirects(redirects);
1458 } else {
1459 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)
;
1460 }
1461
1462 rv = mQuery->GetSuggestedFileName(mFileName);
1463 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !mFileName.IsEmpty()) {
1464 mIsBinaryFile = IsBinary(mFileName);
1465 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)
1466 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)
;
1467 } else {
1468 nsAutoCString errorName;
1469 mozilla::GetErrorName(rv, errorName);
1470 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)
;
1471 mFileName.Truncate();
1472 }
1473
1474 // We can skip parsing certificate for non-binary files because we only
1475 // check local block list for them.
1476 if (mIsBinaryFile) {
1477 nsTArray<nsTArray<nsTArray<uint8_t>>> sigArray;
1478 rv = mQuery->GetSignatureInfo(sigArray);
1479 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1479); return rv; } } while (false)
;
1480
1481 if (!sigArray.IsEmpty()) {
1482 rv = ParseCertificates(sigArray);
1483 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1483); return rv; } } while (false)
;
1484 }
1485
1486 rv = GenerateWhitelistStrings();
1487 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1487); return rv; } } while (false)
;
1488 }
1489
1490 // Start the call chain.
1491 return LookupNext();
1492}
1493
1494nsresult PendingLookup::OnComplete(uint32_t aVerdict, Reason aReason,
1495 nsresult aRv) {
1496 if (NS_FAILED(aRv)((bool)(__builtin_expect(!!(NS_FAILED_impl(aRv)), 0)))) {
1497 nsAutoCString errorName;
1498 mozilla::GetErrorName(aRv, errorName);
1499 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
)
1500 ("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
)
1501 "[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
)
1502 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
)
;
1503 }
1504
1505 if (mTimeoutTimer) {
1506 mTimeoutTimer->Cancel();
1507 mTimeoutTimer = nullptr;
1508 }
1509
1510 bool shouldBlock = true;
1511 switch (aVerdict) {
1512 case nsIApplicationReputationService::VERDICT_DANGEROUS:
1513 if (!Preferences::GetBool(PREF_BLOCK_DANGEROUS"browser.safebrowsing.downloads.remote.block_dangerous", true)) {
1514 shouldBlock = false;
1515 aReason = Reason::eDangerousprefoff;
1516 }
1517 break;
1518 case nsIApplicationReputationService::VERDICT_UNCOMMON:
1519 if (!Preferences::GetBool(PREF_BLOCK_UNCOMMON"browser.safebrowsing.downloads.remote.block_uncommon", true)) {
1520 shouldBlock = false;
1521 aReason = Reason::eUncommonprefoff;
1522 }
1523 break;
1524 case nsIApplicationReputationService::VERDICT_POTENTIALLY_UNWANTED:
1525 if (!Preferences::GetBool(PREF_BLOCK_POTENTIALLY_UNWANTED"browser.safebrowsing.downloads.remote.block_potentially_unwanted", true)) {
1526 shouldBlock = false;
1527 aReason = Reason::eUnwantedprefoff;
1528 }
1529 break;
1530 case nsIApplicationReputationService::VERDICT_DANGEROUS_HOST:
1531 if (!Preferences::GetBool(PREF_BLOCK_DANGEROUS_HOST"browser.safebrowsing.downloads.remote.block_dangerous_host", true)) {
1532 shouldBlock = false;
1533 aReason = Reason::eDangeroushostprefoff;
1534 }
1535 break;
1536 default:
1537 shouldBlock = false;
1538 break;
1539 }
1540
1541 mozilla::glean::application_reputation::reason.EnumGet(aReason).Add();
1542 mozilla::glean::application_reputation::should_block
1543 .EnumGet(
1544 static_cast<mozilla::glean::application_reputation::ShouldBlockLabel>(
1545 shouldBlock))
1546 .Add();
1547
1548 double t = (TimeStamp::Now() - mStartTime).ToMilliseconds();
1549 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)
1550 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)
;
1551 if (shouldBlock) {
1552 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)
1553 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)
;
1554 } else {
1555 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)
;
1556 }
1557
1558 nsresult res = mCallback->OnComplete(shouldBlock, aRv, aVerdict);
1559 return res;
1560}
1561
1562nsresult PendingLookup::ParseCertificates(
1563 const nsTArray<nsTArray<nsTArray<uint8_t>>>& aSigArray) {
1564 // Binaries may be signed by multiple chains of certificates. If there are no
1565 // chains, the binary is unsigned (or we were unable to extract signature
1566 // information on a non-Windows platform)
1567
1568 // Each chain may have multiple certificates.
1569 for (const auto& certList : aSigArray) {
1570 safe_browsing::ClientDownloadRequest_CertificateChain* certChain =
1571 mRequest.mutable_signature()->add_certificate_chain();
1572 for (const auto& cert : certList) {
1573 // Add this certificate to the protobuf to send remotely.
1574 certChain->add_element()->set_certificate(cert.Elements(), cert.Length());
1575 }
1576 }
1577 if (mRequest.signature().certificate_chain_size() > 0) {
1578 mRequest.mutable_signature()->set_trusted(true);
1579 }
1580 return NS_OK;
1581}
1582
1583nsresult PendingLookup::SendRemoteQuery() {
1584 MOZ_ASSERT(!IsFileType(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!IsFileType( mFileName, ApplicationReputationService
::kNonBinaryExecutables, std::size(ApplicationReputationService
::kNonBinaryExecutables)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!IsFileType( mFileName, ApplicationReputationService
::kNonBinaryExecutables, std::size(ApplicationReputationService
::kNonBinaryExecutables))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, std::size(ApplicationReputationService::kNonBinaryExecutables))"
, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1586); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, std::size(ApplicationReputationService::kNonBinaryExecutables))"
")"); do { MOZ_CrashSequence(__null, 1586); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1585 mFileName, ApplicationReputationService::kNonBinaryExecutables,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!IsFileType( mFileName, ApplicationReputationService
::kNonBinaryExecutables, std::size(ApplicationReputationService
::kNonBinaryExecutables)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!IsFileType( mFileName, ApplicationReputationService
::kNonBinaryExecutables, std::size(ApplicationReputationService
::kNonBinaryExecutables))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, std::size(ApplicationReputationService::kNonBinaryExecutables))"
, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1586); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, std::size(ApplicationReputationService::kNonBinaryExecutables))"
")"); do { MOZ_CrashSequence(__null, 1586); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1586 std::size(ApplicationReputationService::kNonBinaryExecutables)))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!IsFileType( mFileName, ApplicationReputationService
::kNonBinaryExecutables, std::size(ApplicationReputationService
::kNonBinaryExecutables)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!IsFileType( mFileName, ApplicationReputationService
::kNonBinaryExecutables, std::size(ApplicationReputationService
::kNonBinaryExecutables))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, std::size(ApplicationReputationService::kNonBinaryExecutables))"
, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1586); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, std::size(ApplicationReputationService::kNonBinaryExecutables))"
")"); do { MOZ_CrashSequence(__null, 1586); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1587 Reason reason = Reason::eNotset;
1588 nsresult rv = SendRemoteQueryInternal(reason);
1589 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1590 return OnComplete(nsIApplicationReputationService::VERDICT_SAFE, reason,
1591 rv);
1592 }
1593 // SendRemoteQueryInternal has fired off the query and we call OnComplete in
1594 // the nsIStreamListener.onStopRequest.
1595 return rv;
1596}
1597
1598nsresult PendingLookup::SendRemoteQueryInternal(Reason& aReason) {
1599 auto scopeExit = mozilla::MakeScopeExit([&aReason]() {
1600 if (aReason == Reason::eNotset) {
1601 aReason = Reason::eInternalerror;
1602 }
1603 });
1604
1605 // If we aren't supposed to do remote lookups, bail.
1606 if (!Preferences::GetBool(PREF_SB_DOWNLOADS_REMOTE_ENABLED"browser.safebrowsing.downloads.remote.enabled", false)) {
1607 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)
;
1608 aReason = Reason::eRemotelookupdisabled;
1609 return NS_ERROR_NOT_AVAILABLE;
1610 }
1611 // If the remote lookup URL is empty or absent, bail.
1612 nsString serviceUrl;
1613 nsCOMPtr<nsIURLFormatter> formatter(
1614 do_GetService("@mozilla.org/toolkit/URLFormatterService;1"));
1615 if (!formatter ||
1616 NS_FAILED(formatter->FormatURLPref(((bool)(__builtin_expect(!!(NS_FAILED_impl(formatter->FormatURLPref
( NS_ConvertASCIItoUTF16("browser.safebrowsing.downloads.remote.url"
), serviceUrl))), 0)))
1617 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)))
||
1618 serviceUrl.IsEmpty() || u"about:blank"_ns.Equals(serviceUrl)) {
1619 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)
;
1620 aReason = Reason::eRemotelookupdisabled;
1621 return NS_ERROR_NOT_AVAILABLE;
1622 }
1623
1624 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)
;
1625 // We did not find a local result, so fire off the query to the
1626 // application reputation service.
1627 nsCOMPtr<nsIURI> uri;
1628 nsresult rv;
1629 rv = mQuery->GetSourceURI(getter_AddRefs(uri));
1630 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1630); return rv; } } while (false)
;
1631 nsCString spec;
1632 rv = GetStrippedSpec(uri, spec);
1633 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1633); return rv; } } while (false)
;
1634 mRequest.set_url(spec.get());
1635
1636 uint32_t fileSize;
1637 rv = mQuery->GetFileSize(&fileSize);
1638 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1638); return rv; } } while (false)
;
1639 mRequest.set_length(fileSize);
1640 // We have no way of knowing whether or not a user initiated the
1641 // download. Set it to true to lessen the chance of false positives.
1642 mRequest.set_user_initiated(true);
1643
1644 nsCString locale;
1645 rv = LocaleService::GetInstance()->GetAppLocaleAsBCP47(locale);
1646 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1646); return rv; } } while (false)
;
1647 mRequest.set_locale(locale.get());
1648 nsCString sha256Hash;
1649 rv = mQuery->GetSha256Hash(sha256Hash);
1650 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1650); return rv; } } while (false)
;
1651 mRequest.mutable_digests()->set_sha256(
1652 std::string(sha256Hash.Data(), sha256Hash.Length()));
1653 mRequest.set_file_basename(mFileName.get());
1654 mRequest.set_download_type(GetDownloadType(mFileName));
1655
1656 if (mRequest.signature().trusted()) {
1657 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)
1658 ("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)
1659 "[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)
1660 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)
;
1661 } else {
1662 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)
1663 ("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)
1664 "[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)
1665 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)
;
1666 }
1667
1668 // Serialize the protocol buffer to a string. This can only fail if we are
1669 // out of memory, or if the protocol buffer req is missing required fields
1670 // (only the URL for now).
1671 std::string serialized;
1672 if (!mRequest.SerializeToString(&serialized)) {
1673 return NS_ERROR_UNEXPECTED;
1674 }
1675
1676 if (LOG_ENABLED()(__builtin_expect(!!(mozilla::detail::log_test(ApplicationReputationService
::prlog, mozilla::LogLevel::Debug)), 0))
) {
1677 nsAutoCString serializedStr(serialized.c_str(), serialized.length());
1678 serializedStr.ReplaceSubstring("\0"_ns, "\\0"_ns);
1679
1680 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)
1681 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)
;
1682 }
1683
1684 // Set the input stream to the serialized protocol buffer
1685 nsCOMPtr<nsIStringInputStream> sstream =
1686 do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
1687 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1687); return rv; } } while (false)
;
1688
1689 rv = sstream->CopyData(serialized.c_str(), serialized.length());
1690 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1690); return rv; } } while (false)
;
1691
1692 // Set up the channel to transmit the request to the service.
1693 nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID"@mozilla.org/network/io-service;1", &rv);
1694 rv = ios->NewChannel(NS_ConvertUTF16toUTF8(serviceUrl), nullptr, nullptr,
1695 nullptr, // aLoadingNode
1696 nsContentUtils::GetSystemPrincipal(),
1697 nullptr, // aTriggeringPrincipal
1698 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
1699 nsIContentPolicy::TYPE_OTHER, getter_AddRefs(mChannel));
1700 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1700); return rv; } } while (false)
;
1701
1702 mChannel->SetLoadFlags(nsIChannel::LOAD_BYPASS_URL_CLASSIFIER);
1703
1704 nsCOMPtr<nsILoadInfo> loadInfo = mChannel->LoadInfo();
1705 mozilla::OriginAttributes attrs;
1706 attrs.mFirstPartyDomain.AssignLiteral(NECKO_SAFEBROWSING_FIRST_PARTY_DOMAIN"safebrowsing.86868755-6b82-4842-b301-72671a0db32e.mozilla");
1707 loadInfo->SetOriginAttributes(attrs);
1708
1709 nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel, &rv));
1710 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1710); return rv; } } while (false)
;
1711 (void)httpChannel;
1712
1713 // Upload the protobuf to the application reputation service.
1714 nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(mChannel, &rv);
1715 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1715); return rv; } } while (false)
;
1716
1717 rv = uploadChannel->ExplicitSetUploadStream(
1718 sstream, "application/octet-stream"_ns, serialized.size(), "POST"_ns);
1719 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1719); return rv; } } while (false)
;
1720
1721 uint32_t timeoutMs =
1722 Preferences::GetUint(PREF_SB_DOWNLOADS_REMOTE_TIMEOUT"browser.safebrowsing.downloads.remote.timeout_ms", 10000);
1723 NS_NewTimerWithCallback(getter_AddRefs(mTimeoutTimer), this, timeoutMs,
1724 nsITimer::TYPE_ONE_SHOT);
1725
1726 mTelemetryRemoteRequestStartMs = PR_IntervalNow();
1727
1728 rv = mChannel->AsyncOpen(this);
1729 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1729); return rv; } } while (false)
;
1730
1731 return NS_OK;
1732}
1733
1734NS_IMETHODIMPnsresult
1735PendingLookup::Notify(nsITimer* aTimer) {
1736 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)
;
1737 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"
, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1737); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aTimer == mTimeoutTimer"
")"); do { MOZ_CrashSequence(__null, 1737); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1738 mozilla::glean::application_reputation::remote_lookup_timeout
1739 .EnumGet(mozilla::glean::application_reputation::
1740 RemoteLookupTimeoutLabel::eTrue)
1741 .Add();
1742 mChannel->Cancel(NS_ERROR_NET_TIMEOUT_EXTERNAL);
1743 mTimeoutTimer->Cancel();
1744 return NS_OK;
1745}
1746
1747NS_IMETHODIMPnsresult
1748PendingLookup::GetName(nsACString& aName) {
1749 aName.AssignLiteral("PendingLookup");
1750 return NS_OK;
1751}
1752
1753///////////////////////////////////////////////////////////////////////////////
1754// nsIObserver implementation
1755NS_IMETHODIMPnsresult
1756PendingLookup::Observe(nsISupports* aSubject, const char* aTopic,
1757 const char16_t* aData) {
1758 if (!strcmp(aTopic, "quit-application")) {
1759 if (mTimeoutTimer) {
1760 mTimeoutTimer->Cancel();
1761 mTimeoutTimer = nullptr;
1762 }
1763 if (mChannel) {
1764 mChannel->Cancel(NS_ERROR_ABORT);
1765 }
1766 }
1767 return NS_OK;
1768}
1769
1770////////////////////////////////////////////////////////////////////////////////
1771//// nsIStreamListener
1772static nsresult AppendSegmentToString(nsIInputStream* inputStream,
1773 void* closure, const char* rawSegment,
1774 uint32_t toOffset, uint32_t count,
1775 uint32_t* writeCount) {
1776 nsAutoCString* decodedData = static_cast<nsAutoCString*>(closure);
1777 decodedData->Append(rawSegment, count);
1778 *writeCount = count;
1779 return NS_OK;
1780}
1781
1782NS_IMETHODIMPnsresult
1783PendingLookup::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aStream,
1784 uint64_t offset, uint32_t count) {
1785 uint32_t read;
1786 return aStream->ReadSegments(AppendSegmentToString, &mResponse, count, &read);
1787}
1788
1789NS_IMETHODIMPnsresult
1790PendingLookup::OnStartRequest(nsIRequest* aRequest) { return NS_OK; }
1791
1792NS_IMETHODIMPnsresult
1793PendingLookup::OnStopRequest(nsIRequest* aRequest, nsresult aResult) {
1794 NS_ENSURE_STATE(mCallback)do { if ((__builtin_expect(!!(!(mCallback)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mCallback" ") failed", nullptr
, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1794); return NS_ERROR_UNEXPECTED; } } while (false)
;
1795
1796 if (aResult != NS_ERROR_NET_TIMEOUT_EXTERNAL) {
1797 mozilla::glean::application_reputation::remote_lookup_timeout
1798 .EnumGet(mozilla::glean::application_reputation::
1799 RemoteLookupTimeoutLabel::eFalse)
1800 .Add();
1801
1802 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"
, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1802); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mTelemetryRemoteRequestStartMs > 0"
")"); do { MOZ_CrashSequence(__null, 1802); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1803 int32_t msecs = PR_IntervalToMilliseconds(PR_IntervalNow() -
1804 mTelemetryRemoteRequestStartMs);
1805
1806 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",
"./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1806); AnnotateMozCrashReason("MOZ_ASSERT" "(" "msecs >= 0"
")"); do { MOZ_CrashSequence(__null, 1806); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1807 mozilla::glean::application_reputation::remote_lookup_response_time
1808 .AccumulateRawDuration(mozilla::TimeDuration::FromMilliseconds(msecs));
1809 }
1810
1811 uint32_t verdict = nsIApplicationReputationService::VERDICT_SAFE;
1812 Reason reason = Reason::eNotset;
1813 nsresult rv = OnStopRequestInternal(aRequest, aResult, verdict, reason);
1814 OnComplete(verdict, reason, rv);
1815 return rv;
1816}
1817
1818nsresult PendingLookup::OnStopRequestInternal(nsIRequest* aRequest,
1819 nsresult aResult,
1820 uint32_t& aVerdict,
1821 Reason& aReason) {
1822 auto scopeExit = mozilla::MakeScopeExit([&aReason]() {
1823 // If |aReason| is not set while exiting, there must be an error.
1824 if (aReason == Reason::eNotset) {
1825 aReason = Reason::eNetworkerror;
1826 }
1827 });
1828
1829 if (NS_FAILED(aResult)((bool)(__builtin_expect(!!(NS_FAILED_impl(aResult)), 0)))) {
1830 mozilla::glean::application_reputation::server.AccumulateSingleSample(
1831 SERVER_RESPONSE_FAILED);
1832 mozilla::glean::application_reputation::server_2
1833 .EnumGet(NSErrorToLabel(aResult))
1834 .Add();
1835 return aResult;
1836 }
1837
1838 nsresult rv;
1839 nsCOMPtr<nsIHttpChannel> channel = do_QueryInterface(aRequest, &rv);
1840 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1841 mozilla::glean::application_reputation::server.AccumulateSingleSample(
1842 SERVER_RESPONSE_FAILED);
1843 mozilla::glean::application_reputation::server_2
1844 .EnumGet(mozilla::glean::application_reputation::Server2Label::
1845 eFailgetchannel)
1846 .Add();
1847 return rv;
1848 }
1849
1850 uint32_t status = 0;
1851 rv = channel->GetResponseStatus(&status);
1852 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1853 mozilla::glean::application_reputation::server.AccumulateSingleSample(
1854 SERVER_RESPONSE_FAILED);
1855 mozilla::glean::application_reputation::server_2
1856 .EnumGet(mozilla::glean::application_reputation::Server2Label::
1857 eFailgetresponse)
1858 .Add();
1859 return rv;
1860 }
1861
1862 if (status != 200) {
1863 mozilla::glean::application_reputation::server.AccumulateSingleSample(
1864 SERVER_RESPONSE_FAILED);
1865 mozilla::glean::application_reputation::server_2
1866 .EnumGet(HTTPStatusToLabel(status))
1867 .Add();
1868 return NS_ERROR_NOT_AVAILABLE;
1869 }
1870
1871 std::string buf(mResponse.Data(), mResponse.Length());
1872 safe_browsing::ClientDownloadResponse response;
1873 if (!response.ParseFromString(buf)) {
1874 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)
1875 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)
;
1876 mozilla::glean::application_reputation::server.AccumulateSingleSample(
1877 SERVER_RESPONSE_INVALID);
1878 return NS_ERROR_CANNOT_CONVERT_DATA;
1879 }
1880
1881 mozilla::glean::application_reputation::server.AccumulateSingleSample(
1882 SERVER_RESPONSE_VALID);
1883 mozilla::glean::application_reputation::server_2
1884 .EnumGet(
1885 mozilla::glean::application_reputation::Server2Label::eResponsevalid)
1886 .Add();
1887
1888 // Clamp responses 0-7, we only know about 0-4 for now.
1889 mozilla::glean::application_reputation::server_verdict.AccumulateSingleSample(
1890 std::min<uint32_t>(response.verdict(), 7));
1891 const char* ext = GetFileExt(mFileName);
1892 mozilla::glean::application_reputation::server_verdict_2.Get(
1893 nsCString(ext),
1894 VerdictToLabel(std::min<uint32_t>(response.verdict(), 7)));
1895 switch (response.verdict()) {
1896 case safe_browsing::ClientDownloadResponse::DANGEROUS:
1897 aVerdict = nsIApplicationReputationService::VERDICT_DANGEROUS;
1898 aReason = Reason::eVerdictdangerous;
1899 break;
1900 case safe_browsing::ClientDownloadResponse::DANGEROUS_HOST:
1901 aVerdict = nsIApplicationReputationService::VERDICT_DANGEROUS_HOST;
1902 aReason = Reason::eVerdictdangeroushost;
1903 break;
1904 case safe_browsing::ClientDownloadResponse::POTENTIALLY_UNWANTED:
1905 aVerdict = nsIApplicationReputationService::VERDICT_POTENTIALLY_UNWANTED;
1906 aReason = Reason::eVerdictunwanted;
1907 break;
1908 case safe_browsing::ClientDownloadResponse::UNCOMMON:
1909 aVerdict = nsIApplicationReputationService::VERDICT_UNCOMMON;
1910 aReason = Reason::eVerdictuncommon;
1911 break;
1912 case safe_browsing::ClientDownloadResponse::UNKNOWN:
1913 aVerdict = nsIApplicationReputationService::VERDICT_SAFE;
1914 aReason = Reason::eVerdictunknown;
1915 break;
1916 case safe_browsing::ClientDownloadResponse::SAFE:
1917 aVerdict = nsIApplicationReputationService::VERDICT_SAFE;
1918 aReason = Reason::eVerdictsafe;
1919 break;
1920 default:
1921 // Treat everything else as safe
1922 aVerdict = nsIApplicationReputationService::VERDICT_SAFE;
1923 aReason = Reason::eVerdictunrecognized;
1924 break;
1925 }
1926
1927 return NS_OK;
1928}
1929
1930NS_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" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1930); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 1930
); __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" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1930); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"ApplicationReputationService\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 1930); __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" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1930); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 1930
); __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" ")", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1930); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"ApplicationReputationService\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 1930); __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", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1930); 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(std::size(table) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
1931
1932ApplicationReputationService*
1933 ApplicationReputationService::gApplicationReputationService = nullptr;
1934
1935already_AddRefed<ApplicationReputationService>
1936ApplicationReputationService::GetSingleton() {
1937 if (!gApplicationReputationService) {
1938 // Note: This is cleared in the new ApplicationReputationService destructor.
1939 gApplicationReputationService = new ApplicationReputationService();
1940 }
1941 return do_AddRef(gApplicationReputationService);
1942}
1943
1944ApplicationReputationService::ApplicationReputationService() {
1945 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)
;
1946}
1947
1948ApplicationReputationService::~ApplicationReputationService() {
1949 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)
;
1950 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"
, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1950); AnnotateMozCrashReason("MOZ_ASSERT" "(" "gApplicationReputationService == this"
")"); do { MOZ_CrashSequence(__null, 1950); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1951 gApplicationReputationService = nullptr;
1952}
1953
1954NS_IMETHODIMPnsresult
1955ApplicationReputationService::QueryReputation(
1956 nsIApplicationReputationQuery* aQuery,
1957 nsIApplicationReputationCallback* aCallback) {
1958 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)
;
1959 NS_ENSURE_ARG_POINTER(aQuery)do { if ((__builtin_expect(!!(!(aQuery)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aQuery" ") failed", nullptr
, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1959); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1960 NS_ENSURE_ARG_POINTER(aCallback)do { if ((__builtin_expect(!!(!(aCallback)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aCallback" ") failed", nullptr
, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1960); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1961
1962 nsresult rv = QueryReputationInternal(aQuery, aCallback);
1963 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1964 Reason reason = rv == NS_ERROR_NOT_AVAILABLE ? Reason::eDpdisabled
1965 : Reason::eInternalerror;
1966
1967 mozilla::glean::application_reputation::reason.EnumGet(reason).Add();
1968 mozilla::glean::application_reputation::should_block
1969 .EnumGet(
1970 mozilla::glean::application_reputation::ShouldBlockLabel::eFalse)
1971 .Add();
1972
1973 aCallback->OnComplete(false, rv,
1974 nsIApplicationReputationService::VERDICT_SAFE);
1975 }
1976 return NS_OK;
1977}
1978
1979nsresult ApplicationReputationService::QueryReputationInternal(
1980 nsIApplicationReputationQuery* aQuery,
1981 nsIApplicationReputationCallback* aCallback) {
1982 // If malware checks aren't enabled, don't query application reputation.
1983 if (!Preferences::GetBool(PREF_SB_MALWARE_ENABLED"browser.safebrowsing.malware.enabled", false)) {
1984 return NS_ERROR_NOT_AVAILABLE;
1985 }
1986
1987 if (!Preferences::GetBool(PREF_SB_DOWNLOADS_ENABLED"browser.safebrowsing.downloads.enabled", false)) {
1988 return NS_ERROR_NOT_AVAILABLE;
1989 }
1990
1991 nsCOMPtr<nsIURI> uri;
1992 nsresult rv = aQuery->GetSourceURI(getter_AddRefs(uri));
1993 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, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1993); return rv; } } while (false)
;
1994 // Bail if the URI hasn't been set.
1995 NS_ENSURE_STATE(uri)do { if ((__builtin_expect(!!(!(uri)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "uri" ") failed", nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1995); return NS_ERROR_UNEXPECTED; } } while (false)
;
1996
1997 // Create a new pending lookup and start the call chain.
1998 RefPtr<PendingLookup> lookup(new PendingLookup(aQuery, aCallback));
1999
2000 // Add an observer for shutdown
2001 nsCOMPtr<nsIObserverService> observerService =
2002 mozilla::services::GetObserverService();
2003 if (!observerService) {
2004 return NS_ERROR_FAILURE;
2005 }
2006
2007 observerService->AddObserver(lookup, "quit-application", true);
2008 return lookup->StartLookup();
2009}
2010
2011nsresult ApplicationReputationService::IsBinary(const nsACString& aFileName,
2012 bool* aBinary) {
2013 *aBinary = ::IsBinary(aFileName);
2014 return NS_OK;
2015}
2016
2017nsresult ApplicationReputationService::IsExecutable(const nsACString& aFileName,
2018 bool* aExecutable) {
2019 *aExecutable =
2020 ::IsFileType(aFileName, sExecutableExts, std::size(sExecutableExts));
2021 return NS_OK;
2022}