Bug Summary

File:root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/components/reputationservice/./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp
Warning:line 1456, 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-19-161322-621273-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 //".searchConnector-ms", exec // Windows Search Connector
437 ".seplugin", // AppleScript
438 ".service", // Systemd service unit file
439 //".settingcontent-ms", exec // Windows settings
440 ".sh", // Linux shell
441 ".shar", // Linux shell
442 //".shb", exec // Windows
443 //".shs", exec // Windows shell
444 ".sht", // HTML
445 ".shtm", // HTML
446 ".shtml", // HTML
447 ".sldm", // MS PowerPoint
448 ".sldx", // MS PowerPoint
449 ".slk", // MS Excel
450 ".slp", // Linux package
451 ".smi", // Mac disk image
452 ".sparsebundle", // Mac disk image
453 ".sparseimage", // Mac disk image
454 ".spl", // Adobe Flash
455 //".squashfs",
456 ".svg",
457 ".swf", // Adobe Flash
458 ".swm", // Windows Imaging
459 ".sys", // Windows
460 ".tar", // Linux archive
461 ".taz", // Linux archive (bzip2)
462 ".tbz", // Linux archive (bzip2)
463 ".tbz2", // Linux archive (bzip2)
464 ".tcsh", // Linux shell
465 //".tif",
466 ".tgz", // Linux archive (gzip)
467 //".toast", // Roxio disk image
468 ".torrent", // Bittorrent
469 ".tpz", // Linux archive (gzip)
470 //".txt",
471 ".txz", // Linux archive (xz)
472 ".tz", // Linux archive (gzip)
473 //".u3p", // U3 Smart Apps
474 ".udf", // MS Excel
475 ".udif", // Mac disk image
476 //".url", exec // Windows
477 //".uu",
478 //".uue",
479 //".vb", exec // Visual Basic script
480 //".vbe", exec // Visual Basic script
481 //".vbs", exec // Visual Basic script
482 //".vbscript", // Visual Basic script
483 //".vdx", exec // MS Visio
484 ".vhd", // Windows virtual hard drive
485 ".vhdx", // Windows virtual hard drive
486 ".vmdk", // VMware virtual disk
487 //".vsd", exec // MS Visio
488 //".vsdm", exec // MS Visio
489 //".vsdx", exec // MS Visio
490 //".vsmacros", exec // MS Visual Studio
491 //".vss", exec // MS Visio
492 //".vssm", exec // MS Visio
493 //".vssx", exec // MS Visio
494 //".vst", exec // MS Visio
495 //".vstm", exec // MS Visio
496 //".vstx", exec // MS Visio
497 //".vsw", exec // MS Visio
498 //".vsx", exec // MS Visio
499 //".vtx", exec // MS Visio
500 //".wav",
501 //".webloc", // MacOS website location file
502 //".webp",
503 ".website", // Windows
504 ".wflow", // Automator action
505 ".wim", // Windows Imaging
506 ".workflow", // Mac Automator
507 //".wrc", // FreeArc archive
508 //".ws", exec // Windows script
509 ".wsb", // Windows Sandbox configuration
510 //".wsc", exec // Windows script
511 //".wsf", exec // Windows script
512 //".wsh", exec // Windows script
513 ".xar", // MS Excel
514 ".xbap", // XAML Browser Application
515 ".xht",
516 ".xhtm",
517 ".xhtml",
518 ".xip", // Mac archive
519 ".xla", // MS Excel
520 ".xlam", // MS Excel
521 ".xldm", // MS Excel
522 //".xll", exec // MS Excel
523 ".xlm", // MS Excel
524 ".xls", // MS Excel
525 ".xlsb", // MS Excel
526 ".xlsm", // MS Excel
527 ".xlsx", // MS Excel
528 ".xlt", // MS Excel
529 ".xltm", // MS Excel
530 ".xltx", // MS Excel
531 ".xlw", // MS Excel
532 ".xml", // MS Excel
533 ".xnk", // MS Exchange
534 //".xrm-ms", exec // Windows
535 ".xsd", // XML schema definition
536 ".xsl", // XML Stylesheet
537 //".xxe",
538 ".xz", // Linux archive (xz)
539 ".z", // InstallShield
540#ifdef XP_WIN // disable on Mac/Linux, see 1167493
541 ".zip", // Generic archive
542#endif
543 ".zipx", // WinZip
544 //".zpaq",
545};
546
547static const char* const kMozNonBinaryExecutables[] = {
548 ".001", ".7z", ".ace", ".arc", ".arj", ".b64", ".balz",
549 ".bhx", ".cpio", ".fat", ".lha", ".lpaq1", ".lpaq5", ".lpaq8",
550 ".lzh", ".lzma", ".ntfs", ".paq8f", ".paq8jd", ".paq8l", ".paq8o",
551 ".pea", ".quad", ".r00", ".r01", ".r02", ".r03", ".r04",
552 ".r05", ".r06", ".r07", ".r08", ".r09", ".r10", ".r11",
553 ".r12", ".r13", ".r14", ".r15", ".r16", ".r17", ".r18",
554 ".r19", ".r20", ".r21", ".r22", ".r23", ".r24", ".r25",
555 ".r26", ".r27", ".r28", ".r29", ".rar", ".squashfs", ".uu",
556 ".uue", ".wrc", ".xxe", ".zpaq", ".toast",
557};
558
559static const char* const kSafeFileExtensions[] = {
560 ".jpg", ".jpeg", ".mp3", ".mp4", ".png", ".csv", ".ica",
561 ".gif", ".txt", ".package", ".tif", ".webp", ".mkv", ".wav",
562 ".mov", ".paf", ".vbscript", ".ad", ".inx", ".isu", ".job",
563 ".rgs", ".u3p", ".out", ".run", ".bmp", ".css", ".ehtml",
564 ".flac", ".ico", ".jfif", ".m4a", ".m4v", ".mpeg", ".mpg",
565 ".oga", ".ogg", ".ogm", ".ogv", ".opus", ".pjp", ".pjpeg",
566 ".svgz", ".text", ".tiff", ".weba", ".webm", ".xbm",
567};
568
569enum class LookupType { AllowlistOnly, BlocklistOnly, BothLists };
570
571// Define the reasons that download protection service accepts or blocks this
572// download. This is now used for telemetry purposes and xpcshell test. Please
573// also update the xpcshell-test if a reason is added.
574//
575// LocalWhitelist : URL is found in the local whitelist
576// LocalBlocklist : URL is found in the local blocklist
577// NonBinary : The downloaded non-binary file is not found in the
578// local blocklist VerdictSafe : Remote lookup reports the download is
579// safe VerdictUnknown : Remote lookup reports unknown, we treat this as a
580// safe download VerdictDangerous : Remote lookup reports the download is
581// dangerous VerdictDangerousHost : Remote lookup reports the download is from a
582// dangerous host VerdictUnwanted : Remote lookup reports the download is
583// potentially unwatned VerdictUncommon : Remote lookup reports the
584// download is uncommon VerdictUnrecognized : The verdict type from remote
585// lookup is not defined in the csd.proto DangerousPrefOff : The download is
586// dangerous, but the corresponding preference is off DangerousHostPrefOff : The
587// download is from a dangerous host, but the corresponding preference is off
588// UnwantedPrefOff : The download is potentially unwanted, but the
589// corresponding preference is off UncommonPrefOff : The download us
590// uncommon, but the coressponding preference is off NetworkError :
591// There is an error while requesting remote lookup RemoteLookupDisabled :
592// Remote lookup is disabled or the remote lookup URL is empty InternalError :
593// An unexpected internal error DPDisabled : Download protection is
594// disabled
595using Reason = mozilla::glean::application_reputation::ReasonLabel;
596
597class PendingDBLookup;
598
599// A single use class private to ApplicationReputationService encapsulating an
600// nsIApplicationReputationQuery and an nsIApplicationReputationCallback. Once
601// created by ApplicationReputationService, it is guaranteed to call mCallback.
602// This class is private to ApplicationReputationService.
603class PendingLookup final : public nsIStreamListener,
604 public nsITimerCallback,
605 public nsINamed,
606 public nsIObserver,
607 public nsSupportsWeakReference {
608 public:
609 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:
610 NS_DECL_NSIREQUESTOBSERVERvirtual nsresult OnStartRequest(nsIRequest *aRequest) override
; virtual nsresult OnStopRequest(nsIRequest *aRequest, nsresult
aStatusCode) override;
611 NS_DECL_NSISTREAMLISTENERvirtual nsresult OnDataAvailable(nsIRequest *aRequest, nsIInputStream
*aInputStream, uint64_t aOffset, uint32_t aCount) override;
612 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"
); }
613 NS_DECL_NSINAMEDvirtual nsresult GetName(nsACString& aName) override;
614 NS_DECL_NSIOBSERVERvirtual nsresult Observe(nsISupports *aSubject, const char * aTopic
, const char16_t * aData) override;
615
616 // Constructor and destructor.
617 PendingLookup(nsIApplicationReputationQuery* aQuery,
618 nsIApplicationReputationCallback* aCallback);
619
620 // Start the lookup. The lookup may have 2 parts: local and remote. In the
621 // local lookup, PendingDBLookups are created to query the local allow and
622 // blocklists for various URIs associated with this downloaded file. In the
623 // event that no results are found, a remote lookup is sent to the Application
624 // Reputation server.
625 nsresult StartLookup();
626
627 private:
628 ~PendingLookup();
629
630 friend class PendingDBLookup;
631
632 // Telemetry states.
633 // Status of the remote response (valid or not).
634 enum SERVER_RESPONSE_TYPES {
635 SERVER_RESPONSE_VALID = 0,
636 SERVER_RESPONSE_FAILED = 1,
637 SERVER_RESPONSE_INVALID = 2,
638 };
639
640 // The target filename for the downloaded file.
641 nsCString mFileName;
642
643 // True if extension of this file matches any extension in the
644 // kBinaryFileExtensions or sExecutableExts list.
645 bool mIsBinaryFile;
646
647 // Number of blocklist and allowlist hits we have seen.
648 uint32_t mBlocklistCount;
649 uint32_t mAllowlistCount;
650
651 // The query containing metadata about the downloaded file.
652 nsCOMPtr<nsIApplicationReputationQuery> mQuery;
653
654 // The callback with which to report the verdict.
655 nsCOMPtr<nsIApplicationReputationCallback> mCallback;
656
657 // An array of strings created from certificate information used to whitelist
658 // the downloaded file.
659 nsTArray<nsCString> mAllowlistSpecs;
660 // The source URI of the download (i.e. final URI after any redirects).
661 nsTArray<nsCString> mAnylistSpecs;
662 // The referrer and possibly any redirects.
663 nsTArray<nsCString> mBlocklistSpecs;
664
665 // When we started this query
666 TimeStamp mStartTime;
667
668 // The channel used to talk to the remote lookup server
669 nsCOMPtr<nsIChannel> mChannel;
670
671 // Timer to abort this lookup if it takes too long
672 nsCOMPtr<nsITimer> mTimeoutTimer;
673
674 // A protocol buffer for storing things we need in the remote request. We
675 // store the resource chain (redirect information) as well as signature
676 // information extracted using the Windows Authenticode API, if the binary is
677 // signed.
678 ClientDownloadRequest mRequest;
679
680 // The response from the application reputation query. This is read in chunks
681 // as part of our nsIStreamListener implementation and may contain embedded
682 // NULLs.
683 nsCString mResponse;
684
685 // The clock records the start time of a remote lookup request, used by
686 // telemetry.
687 PRIntervalTime mTelemetryRemoteRequestStartMs;
688
689 // Returns the type of download binary for the file.
690 ClientDownloadRequest::DownloadType GetDownloadType(
691 const nsACString& aFilename);
692
693 // Clean up and call the callback. PendingLookup must not be used after this
694 // function is called.
695 nsresult OnComplete(uint32_t aVerdict, Reason aReason, nsresult aRv);
696
697 // Wrapper function for nsIStreamListener.onStopRequest to make it easy to
698 // guarantee calling the callback
699 nsresult OnStopRequestInternal(nsIRequest* aRequest, nsresult aResult,
700 uint32_t& aVerdict, Reason& aReason);
701
702 // Return the hex-encoded hash of the whole URI.
703 nsresult GetSpecHash(nsACString& aSpec, nsACString& hexEncodedHash);
704
705 // Strip url parameters, fragments, and user@pass fields from the URI spec
706 // using nsIURL. Hash data URIs and return blob URIs unfiltered.
707 nsresult GetStrippedSpec(nsIURI* aUri, nsACString& spec);
708
709 // Escape '/' and '%' in certificate attribute values.
710 nsCString EscapeCertificateAttribute(const nsACString& aAttribute);
711
712 // Escape ':' in fingerprint values.
713 nsCString EscapeFingerprint(const nsACString& aAttribute);
714
715 // Generate whitelist strings for the given certificate pair from the same
716 // certificate chain.
717 nsresult GenerateWhitelistStringsForPair(nsIX509Cert* certificate,
718 nsIX509Cert* issuer);
719
720 // Generate whitelist strings for the given certificate chain, which starts
721 // with the signer and may go all the way to the root cert.
722 nsresult GenerateWhitelistStringsForChain(
723 const ClientDownloadRequest_CertificateChain& aChain);
724
725 // For signed binaries, generate strings of the form:
726 // http://sb-ssl.google.com/safebrowsing/csd/certificate/
727 // <issuer_cert_sha1_fingerprint>[/CN=<cn>][/O=<org>][/OU=<unit>]
728 // for each (cert, issuer) pair in each chain of certificates that is
729 // associated with the binary.
730 nsresult GenerateWhitelistStrings();
731
732 // Parse the XPCOM certificate lists and stick them into the protocol buffer
733 // version.
734 nsresult ParseCertificates(
735 const nsTArray<nsTArray<nsTArray<uint8_t>>>& aSigArray);
736
737 // Adds the redirects to mBlocklistSpecs to be looked up.
738 nsresult AddRedirects(nsIArray* aRedirects);
739
740 // Helper function to ensure that we call PendingLookup::LookupNext or
741 // PendingLookup::OnComplete.
742 nsresult DoLookupInternal();
743
744 // Looks up all the URIs that may be responsible for allowlisting or
745 // blocklisting the downloaded file. These URIs may include whitelist strings
746 // generated by certificates verifying the binary as well as the target URI
747 // from which the file was downloaded.
748 nsresult LookupNext();
749
750 // Sends a query to the remote application reputation service. Returns NS_OK
751 // on success.
752 nsresult SendRemoteQuery();
753
754 // Helper function to ensure that we always call the callback.
755 nsresult SendRemoteQueryInternal(Reason& aReason);
756};
757
758// A single-use class for looking up a single URI in the safebrowsing DB. This
759// class is private to PendingLookup.
760class PendingDBLookup final : public nsIUrlClassifierCallback {
761 public:
762 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:
763 NS_DECL_NSIURLCLASSIFIERCALLBACKvirtual nsresult HandleEvent(const nsACString& value) override
;
764
765 // Constructor and destructor
766 explicit PendingDBLookup(PendingLookup* aPendingLookup);
767
768 // Look up the given URI in the safebrowsing DBs, optionally on both the allow
769 // list and the blocklist. If there is a match, call
770 // PendingLookup::OnComplete. Otherwise, call PendingLookup::LookupNext.
771 nsresult LookupSpec(const nsACString& aSpec, const LookupType& aLookupType);
772
773 private:
774 ~PendingDBLookup();
775
776 // The download appeared on the allowlist, blocklist, or no list (and thus
777 // could trigger a remote query.
778 enum LIST_TYPES {
779 ALLOW_LIST = 0,
780 BLOCK_LIST = 1,
781 NO_LIST = 2,
782 };
783
784 nsCString mSpec;
785 LookupType mLookupType;
786 RefPtr<PendingLookup> mPendingLookup;
787 nsresult LookupSpecInternal(const nsACString& aSpec);
788};
789
790NS_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"
, 790); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 790
); __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"
, 790); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingDBLookup\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 790); __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"
, 790); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 790
); __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"
, 790); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingDBLookup\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 790); __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"
, 790); 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; }
791
792PendingDBLookup::PendingDBLookup(PendingLookup* aPendingLookup)
793 : mLookupType(LookupType::BothLists), mPendingLookup(aPendingLookup) {
794 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)
;
795}
796
797PendingDBLookup::~PendingDBLookup() {
798 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)
;
799 mPendingLookup = nullptr;
800}
801
802nsresult PendingDBLookup::LookupSpec(const nsACString& aSpec,
803 const LookupType& aLookupType) {
804 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)
805 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)
;
806 mSpec = aSpec;
807 mLookupType = aLookupType;
808 nsresult rv = LookupSpecInternal(aSpec);
809 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
810 nsAutoCString errorName;
811 mozilla::GetErrorName(rv, errorName);
812 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)
813 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)
;
814 return mPendingLookup->LookupNext(); // ignore this lookup and move to next
815 }
816 // LookupSpecInternal has called nsIUrlClassifierCallback.lookup, which is
817 // guaranteed to call HandleEvent.
818 return rv;
819}
820
821nsresult PendingDBLookup::LookupSpecInternal(const nsACString& aSpec) {
822 nsresult rv;
823
824 nsCOMPtr<nsIURI> uri;
825 nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID"@mozilla.org/network/io-service;1", &rv);
826 rv = ios->NewURI(aSpec, nullptr, nullptr, getter_AddRefs(uri));
827 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"
, 827); return rv; } } while (false)
;
828
829 OriginAttributes attrs;
830 nsCOMPtr<nsIPrincipal> principal =
831 BasePrincipal::CreateContentPrincipal(uri, attrs);
832 if (!principal) {
833 return NS_ERROR_FAILURE;
834 }
835
836 // Check local lists to see if the URI has already been whitelisted or
837 // blacklisted.
838 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)
;
839 nsCOMPtr<nsIUrlClassifierDBService> dbService =
840 mozilla::components::UrlClassifierDB::Service(&rv);
841 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"
, 841); return rv; } } while (false)
;
842
843 nsAutoCString tables;
844 nsAutoCString allowlist;
845 Preferences::GetCString(PREF_DOWNLOAD_ALLOW_TABLE"urlclassifier.downloadAllowTable", allowlist);
846 if ((mLookupType != LookupType::BlocklistOnly) && !allowlist.IsEmpty()) {
847 tables.Append(allowlist);
848 }
849 nsAutoCString blocklist;
850 Preferences::GetCString(PREF_DOWNLOAD_BLOCK_TABLE"urlclassifier.downloadBlockTable", blocklist);
851 if ((mLookupType != LookupType::AllowlistOnly) && !blocklist.IsEmpty()) {
852 if (!tables.IsEmpty()) {
853 tables.Append(',');
854 }
855 tables.Append(blocklist);
856 }
857 if (principal->IsSystemPrincipal()) {
858 return mPendingLookup->LookupNext();
859 }
860 return dbService->Lookup(principal, tables, this);
861}
862
863NS_IMETHODIMPnsresult
864PendingDBLookup::HandleEvent(const nsACString& tables) {
865 // HandleEvent is guaranteed to call either:
866 // 1) PendingLookup::OnComplete if the URL matches the blocklist, or
867 // 2) PendingLookup::LookupNext if the URL does not match the blocklist.
868 // Blocklisting trumps allowlisting.
869 nsAutoCString blockList;
870 Preferences::GetCString(PREF_DOWNLOAD_BLOCK_TABLE"urlclassifier.downloadBlockTable", blockList);
871 if ((mLookupType != LookupType::AllowlistOnly) && !blockList.IsEmpty() &&
872 FindInReadable(blockList, tables)) {
873 mPendingLookup->mBlocklistCount++;
874 mozilla::glean::application_reputation::local.AccumulateSingleSample(
875 BLOCK_LIST);
876 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)
;
877 return mPendingLookup->OnComplete(
878 nsIApplicationReputationService::VERDICT_DANGEROUS,
879 Reason::eLocalblocklist, NS_OK);
880 }
881
882 nsAutoCString allowList;
883 Preferences::GetCString(PREF_DOWNLOAD_ALLOW_TABLE"urlclassifier.downloadAllowTable", allowList);
884 if ((mLookupType != LookupType::BlocklistOnly) && !allowList.IsEmpty() &&
885 FindInReadable(allowList, tables)) {
886 mPendingLookup->mAllowlistCount++;
887 mozilla::glean::application_reputation::local.AccumulateSingleSample(
888 ALLOW_LIST);
889 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)
;
890 // Don't call onComplete, since blocklisting trumps allowlisting
891 return mPendingLookup->LookupNext();
892 }
893
894 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)
;
895 mozilla::glean::application_reputation::local.AccumulateSingleSample(NO_LIST);
896 return mPendingLookup->LookupNext();
897}
898
899NS_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"
, 901); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 901
); __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"
, 901); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 901); __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"
, 901); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 901
); __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"
, 901); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 901); __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"
, 901); 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 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"
, 901); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 901
); __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"
, 901); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 901); __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"
, 901); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 901
); __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"
, 901); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 901); __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"
, 901); 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 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"
, 901); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 901
); __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"
, 901); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 901); __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"
, 901); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 901
); __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"
, 901); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"PendingLookup\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 901); __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"
, 901); 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; }
902
903PendingLookup::PendingLookup(nsIApplicationReputationQuery* aQuery,
904 nsIApplicationReputationCallback* aCallback)
905 : mIsBinaryFile(false),
906 mBlocklistCount(0),
907 mAllowlistCount(0),
908 mQuery(aQuery),
909 mCallback(aCallback) {
910 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)
;
911}
912
913PendingLookup::~PendingLookup() {
914 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)
;
915}
916
917static const char* const kDmgFileExtensions[] = {
918 ".cdr", ".dart", ".dc42", ".diskcopy42",
919 ".dmg", ".dmgpart", ".dvdr", ".img",
920 ".imgpart", ".iso", ".ndif", ".smi",
921 ".sparsebundle", ".sparseimage", ".toast", ".udif",
922};
923
924static const char* const kRarFileExtensions[] = {
925 ".r00", ".r01", ".r02", ".r03", ".r04", ".r05", ".r06", ".r07",
926 ".r08", ".r09", ".r10", ".r11", ".r12", ".r13", ".r14", ".r15",
927 ".r16", ".r17", ".r18", ".r19", ".r20", ".r21", ".r22", ".r23",
928 ".r24", ".r25", ".r26", ".r27", ".r28", ".r29", ".rar",
929};
930
931static const char* const kZipFileExtensions[] = {
932 ".zip", // Generic archive
933 ".zipx", // WinZip
934};
935
936static const char* GetFileExt(const nsACString& aFilename,
937 const char* const aFileExtensions[],
938 const size_t aLength) {
939 for (size_t i = 0; i < aLength; ++i) {
940 if (StringEndsWith(aFilename, nsDependentCString(aFileExtensions[i]),
941 nsCaseInsensitiveCStringComparator)) {
942 return aFileExtensions[i];
943 }
944 }
945 return nullptr;
946}
947
948static const char* GetFileExt(const nsACString& aFilename) {
949#define _GetFileExt(_f, _l)GetFileExt(_f, _l, std::size(_l)) GetFileExt(_f, _l, std::size(_l))
950 const char* ext = _GetFileExt(GetFileExt(aFilename, ApplicationReputationService::kBinaryFileExtensions
, std::size(ApplicationReputationService::kBinaryFileExtensions
))
951 aFilename, ApplicationReputationService::kBinaryFileExtensions)GetFileExt(aFilename, ApplicationReputationService::kBinaryFileExtensions
, std::size(ApplicationReputationService::kBinaryFileExtensions
))
;
952 if (ext == nullptr &&
953 !_GetFileExt(aFilename,GetFileExt(aFilename, ApplicationReputationService::kNonBinaryExecutables
, std::size(ApplicationReputationService::kNonBinaryExecutables
))
954 ApplicationReputationService::kNonBinaryExecutables)GetFileExt(aFilename, ApplicationReputationService::kNonBinaryExecutables
, std::size(ApplicationReputationService::kNonBinaryExecutables
))
) {
955 ext = _GetFileExt(aFilename, sExecutableExts)GetFileExt(aFilename, sExecutableExts, std::size(sExecutableExts
))
;
956 }
957 return ext;
958}
959
960// Returns true if the file extension matches one in the given array.
961static bool IsFileType(const nsACString& aFilename,
962 const char* const aFileExtensions[],
963 const size_t aLength) {
964 return GetFileExt(aFilename, aFileExtensions, aLength) != nullptr;
965}
966
967static bool IsBinary(const nsACString& aFilename) {
968 return IsFileType(
969 aFilename, ApplicationReputationService::kBinaryFileExtensions,
970 std::size(ApplicationReputationService::kBinaryFileExtensions)) ||
971 (!IsFileType(
972 aFilename, ApplicationReputationService::kNonBinaryExecutables,
973 std::size(ApplicationReputationService::kNonBinaryExecutables)) &&
974 IsFileType(aFilename, sExecutableExts, std::size(sExecutableExts)));
975}
976
977ClientDownloadRequest::DownloadType PendingLookup::GetDownloadType(
978 const nsACString& aFilename) {
979 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"
, 979); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsBinary(aFilename)"
")"); do { MOZ_CrashSequence(__null, 979); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
980
981 // Extensions are matched case-insensitively, so compare against a lowercased
982 // copy of the filename.
983 nsAutoCString fileName(aFilename);
984 ToLowerCase(fileName);
985
986 // From
987 // https://cs.chromium.org/chromium/src/chrome/common/safe_browsing/download_protection_util.cc?l=17
988 if (StringEndsWith(fileName, ".zip"_ns)) {
989 return ClientDownloadRequest::ZIPPED_EXECUTABLE;
990 } else if (StringEndsWith(fileName, ".apk"_ns)) {
991 return ClientDownloadRequest::ANDROID_APK;
992 } else if (StringEndsWith(fileName, ".app"_ns) ||
993 StringEndsWith(fileName, ".applescript"_ns) ||
994 StringEndsWith(fileName, ".cdr"_ns) ||
995 StringEndsWith(fileName, ".dart"_ns) ||
996 StringEndsWith(fileName, ".dc42"_ns) ||
997 StringEndsWith(fileName, ".diskcopy42"_ns) ||
998 StringEndsWith(fileName, ".dmg"_ns) ||
999 StringEndsWith(fileName, ".dmgpart"_ns) ||
1000 StringEndsWith(fileName, ".dvdr"_ns) ||
1001 StringEndsWith(fileName, ".img"_ns) ||
1002 StringEndsWith(fileName, ".imgpart"_ns) ||
1003 StringEndsWith(fileName, ".iso"_ns) ||
1004 StringEndsWith(fileName, ".mpkg"_ns) ||
1005 StringEndsWith(fileName, ".ndif"_ns) ||
1006 StringEndsWith(fileName, ".osas"_ns) ||
1007 StringEndsWith(fileName, ".osax"_ns) ||
1008 StringEndsWith(fileName, ".pkg"_ns) ||
1009 StringEndsWith(fileName, ".scpt"_ns) ||
1010 StringEndsWith(fileName, ".scptd"_ns) ||
1011 StringEndsWith(fileName, ".seplugin"_ns) ||
1012 StringEndsWith(fileName, ".smi"_ns) ||
1013 StringEndsWith(fileName, ".sparsebundle"_ns) ||
1014 StringEndsWith(fileName, ".sparseimage"_ns) ||
1015 StringEndsWith(fileName, ".toast"_ns) ||
1016 StringEndsWith(fileName, ".udif"_ns)) {
1017 return ClientDownloadRequest::MAC_EXECUTABLE;
1018 }
1019
1020 return ClientDownloadRequest::WIN_EXECUTABLE; // default to Windows binaries
1021}
1022
1023nsresult PendingLookup::LookupNext() {
1024 // We must call LookupNext or SendRemoteQuery upon return.
1025 // Look up all of the URLs that could allow or block this download.
1026 // Blocklist first.
1027
1028 // If a url is in blocklist we should call PendingLookup::OnComplete directly.
1029 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"
, 1029); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mBlocklistCount == 0"
")"); do { MOZ_CrashSequence(__null, 1029); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1030
1031 nsCString spec;
1032 if (!mAnylistSpecs.IsEmpty()) {
1033 // Check the source URI only.
1034 spec = mAnylistSpecs.PopLastElement();
1035 RefPtr<PendingDBLookup> lookup(new PendingDBLookup(this));
1036
1037 // We don't need to check whitelist if the file is not a binary file.
1038 auto type =
1039 mIsBinaryFile ? LookupType::BothLists : LookupType::BlocklistOnly;
1040 return lookup->LookupSpec(spec, type);
1041 }
1042
1043 if (!mBlocklistSpecs.IsEmpty()) {
1044 // Check the referrer and redirect chain.
1045 spec = mBlocklistSpecs.PopLastElement();
1046 RefPtr<PendingDBLookup> lookup(new PendingDBLookup(this));
1047 return lookup->LookupSpec(spec, LookupType::BlocklistOnly);
1048 }
1049
1050 // Now that we've looked up all of the URIs against the blocklist,
1051 // if any of mAnylistSpecs or mAllowlistSpecs matched the allowlist,
1052 // go ahead and pass.
1053 if (mAllowlistCount > 0) {
1054 return OnComplete(nsIApplicationReputationService::VERDICT_SAFE,
1055 Reason::eLocalwhitelist, NS_OK);
1056 }
1057
1058 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"
, 1058); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAllowlistSpecs.Length() == 0"
")"); do { MOZ_CrashSequence(__null, 1058); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1059
1060 // Only binary signatures remain.
1061 if (!mAllowlistSpecs.IsEmpty()) {
1062 spec = mAllowlistSpecs.PopLastElement();
1063 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)
;
1064 RefPtr<PendingDBLookup> lookup(new PendingDBLookup(this));
1065 return lookup->LookupSpec(spec, LookupType::AllowlistOnly);
1066 }
1067
1068 if (!mFileName.IsEmpty()) {
1069 if (IsBinary(mFileName)) {
1070 mozilla::glean::application_reputation::binary_type
1071 .EnumGet(mozilla::glean::application_reputation::BinaryTypeLabel::
1072 eBinaryfile)
1073 .Add();
1074 } else if (IsFileType(mFileName, kSafeFileExtensions,
1075 std::size(kSafeFileExtensions))) {
1076 mozilla::glean::application_reputation::binary_type
1077 .EnumGet(mozilla::glean::application_reputation::BinaryTypeLabel::
1078 eNonbinaryfile)
1079 .Add();
1080 } else if (IsFileType(mFileName, kMozNonBinaryExecutables,
1081 std::size(kMozNonBinaryExecutables))) {
1082 mozilla::glean::application_reputation::binary_type
1083 .EnumGet(mozilla::glean::application_reputation::BinaryTypeLabel::
1084 eMoznonbinaryfile)
1085 .Add();
1086 } else {
1087 mozilla::glean::application_reputation::binary_type
1088 .EnumGet(mozilla::glean::application_reputation::BinaryTypeLabel::
1089 eUnknownfile)
1090 .Add();
1091 }
1092 } else {
1093 mozilla::glean::application_reputation::binary_type
1094 .EnumGet(mozilla::glean::application_reputation::BinaryTypeLabel::
1095 eMissingfilename)
1096 .Add();
1097 }
1098
1099 if (IsFileType(mFileName, kDmgFileExtensions,
1100 std::size(kDmgFileExtensions))) {
1101 mozilla::glean::application_reputation::binary_archive
1102 .EnumGet(mozilla::glean::application_reputation::BinaryArchiveLabel::
1103 eDmgfile)
1104 .Add();
1105 } else if (IsFileType(mFileName, kRarFileExtensions,
1106 std::size(kRarFileExtensions))) {
1107 mozilla::glean::application_reputation::binary_archive
1108 .EnumGet(mozilla::glean::application_reputation::BinaryArchiveLabel::
1109 eRarfile)
1110 .Add();
1111 } else if (IsFileType(mFileName, kZipFileExtensions,
1112 std::size(kZipFileExtensions))) {
1113 mozilla::glean::application_reputation::binary_archive
1114 .EnumGet(mozilla::glean::application_reputation::BinaryArchiveLabel::
1115 eZipfile)
1116 .Add();
1117 } else if (mIsBinaryFile) {
1118 mozilla::glean::application_reputation::binary_archive
1119 .EnumGet(mozilla::glean::application_reputation::BinaryArchiveLabel::
1120 eOtherbinaryfile)
1121 .Add();
1122 }
1123
1124 // There are no more URIs to check against local list. If the file is
1125 // not eligible for remote lookup, bail.
1126 if (!mIsBinaryFile) {
1127 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)
;
1128 return OnComplete(nsIApplicationReputationService::VERDICT_SAFE,
1129 Reason::eNonbinaryfile, NS_OK);
1130 }
1131
1132 nsresult rv = SendRemoteQuery();
1133 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1134 return OnComplete(nsIApplicationReputationService::VERDICT_SAFE,
1135 Reason::eInternalerror, rv);
1136 }
1137 return NS_OK;
1138}
1139
1140nsCString PendingLookup::EscapeCertificateAttribute(
1141 const nsACString& aAttribute) {
1142 // Escape '/' because it's a field separator, and '%' because Chrome does
1143 nsCString escaped;
1144 escaped.SetCapacity(aAttribute.Length());
1145 for (unsigned int i = 0; i < aAttribute.Length(); ++i) {
1146 if (aAttribute.Data()[i] == '%') {
1147 escaped.AppendLiteral("%25");
1148 } else if (aAttribute.Data()[i] == '/') {
1149 escaped.AppendLiteral("%2F");
1150 } else if (aAttribute.Data()[i] == ' ') {
1151 escaped.AppendLiteral("%20");
1152 } else {
1153 escaped.Append(aAttribute.Data()[i]);
1154 }
1155 }
1156 return escaped;
1157}
1158
1159nsCString PendingLookup::EscapeFingerprint(const nsACString& aFingerprint) {
1160 // Google's fingerprint doesn't have colons
1161 nsCString escaped;
1162 escaped.SetCapacity(aFingerprint.Length());
1163 for (unsigned int i = 0; i < aFingerprint.Length(); ++i) {
1164 if (aFingerprint.Data()[i] != ':') {
1165 escaped.Append(aFingerprint.Data()[i]);
1166 }
1167 }
1168 return escaped;
1169}
1170
1171nsresult PendingLookup::GenerateWhitelistStringsForPair(
1172 nsIX509Cert* certificate, nsIX509Cert* issuer) {
1173 // The whitelist paths have format:
1174 // http://sb-ssl.google.com/safebrowsing/csd/certificate/<issuer_cert_fingerprint>[/CN=<cn>][/O=<org>][/OU=<unit>]
1175 // Any of CN, O, or OU may be omitted from the whitelist entry. Unfortunately
1176 // this is not publicly documented, but the Chrome implementation can be found
1177 // here:
1178 // https://code.google.com/p/chromium/codesearch#search/&q=GetCertificateWhitelistStrings
1179 nsCString whitelistString(
1180 "http://sb-ssl.google.com/safebrowsing/csd/certificate/");
1181
1182 nsString fingerprint;
1183 nsresult rv = issuer->GetSha1Fingerprint(fingerprint);
1184 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"
, 1184); return rv; } } while (false)
;
1185 whitelistString.Append(EscapeFingerprint(NS_ConvertUTF16toUTF8(fingerprint)));
1186
1187 nsString commonName;
1188 rv = certificate->GetCommonName(commonName);
1189 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"
, 1189); return rv; } } while (false)
;
1190 if (!commonName.IsEmpty()) {
1191 whitelistString.AppendLiteral("/CN=");
1192 whitelistString.Append(
1193 EscapeCertificateAttribute(NS_ConvertUTF16toUTF8(commonName)));
1194 }
1195
1196 nsString organization;
1197 rv = certificate->GetOrganization(organization);
1198 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"
, 1198); return rv; } } while (false)
;
1199 if (!organization.IsEmpty()) {
1200 whitelistString.AppendLiteral("/O=");
1201 whitelistString.Append(
1202 EscapeCertificateAttribute(NS_ConvertUTF16toUTF8(organization)));
1203 }
1204
1205 nsString organizationalUnit;
1206 rv = certificate->GetOrganizationalUnit(organizationalUnit);
1207 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"
, 1207); return rv; } } while (false)
;
1208 if (!organizationalUnit.IsEmpty()) {
1209 whitelistString.AppendLiteral("/OU=");
1210 whitelistString.Append(
1211 EscapeCertificateAttribute(NS_ConvertUTF16toUTF8(organizationalUnit)));
1212 }
1213 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)
;
1214
1215 mAllowlistSpecs.AppendElement(whitelistString);
1216 return NS_OK;
1217}
1218
1219nsresult PendingLookup::GenerateWhitelistStringsForChain(
1220 const safe_browsing::ClientDownloadRequest_CertificateChain& aChain) {
1221 // We need a signing certificate and an issuer to construct a whitelist
1222 // entry.
1223 if (aChain.element_size() < 2) {
1224 return NS_OK;
1225 }
1226
1227 // Get the signer.
1228 nsresult rv;
1229 nsCOMPtr<nsIX509CertDB> certDB = do_GetService(NS_X509CERTDB_CONTRACTID"@mozilla.org/security/x509certdb;1", &rv);
1230 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"
, 1230); return rv; } } while (false)
;
1231
1232 nsCOMPtr<nsIX509Cert> signer;
1233 nsTArray<uint8_t> signerBytes;
1234 signerBytes.AppendElements(aChain.element(0).certificate().data(),
1235 aChain.element(0).certificate().size());
1236 rv = certDB->ConstructX509(signerBytes, getter_AddRefs(signer));
1237 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"
, 1237); return rv; } } while (false)
;
1238
1239 for (int i = 1; i < aChain.element_size(); ++i) {
1240 // Get the issuer.
1241 nsCOMPtr<nsIX509Cert> issuer;
1242 nsTArray<uint8_t> issuerBytes;
1243 issuerBytes.AppendElements(aChain.element(i).certificate().data(),
1244 aChain.element(i).certificate().size());
1245 rv = certDB->ConstructX509(issuerBytes, getter_AddRefs(issuer));
1246 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"
, 1246); return rv; } } while (false)
;
1247
1248 rv = GenerateWhitelistStringsForPair(signer, issuer);
1249 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1249); return rv; } } while (false)
;
1250 }
1251 return NS_OK;
1252}
1253
1254nsresult PendingLookup::GenerateWhitelistStrings() {
1255 for (int i = 0; i < mRequest.signature().certificate_chain_size(); ++i) {
1256 nsresult rv = GenerateWhitelistStringsForChain(
1257 mRequest.signature().certificate_chain(i));
1258 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1258); return rv; } } while (false)
;
1259 }
1260 return NS_OK;
1261}
1262
1263nsresult PendingLookup::AddRedirects(nsIArray* aRedirects) {
1264 uint32_t length = 0;
1265 aRedirects->GetLength(&length);
1266 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)
;
1267 nsCOMPtr<nsISimpleEnumerator> iter;
1268 nsresult rv = aRedirects->Enumerate(getter_AddRefs(iter));
1269 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"
, 1269); return rv; } } while (false)
;
1270
1271 bool hasMoreRedirects = false;
1272 rv = iter->HasMoreElements(&hasMoreRedirects);
1273 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"
, 1273); return rv; } } while (false)
;
1274
1275 while (hasMoreRedirects) {
1276 nsCOMPtr<nsISupports> supports;
1277 rv = iter->GetNext(getter_AddRefs(supports));
1278 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"
, 1278); return rv; } } while (false)
;
1279
1280 nsCOMPtr<nsIRedirectHistoryEntry> redirectEntry =
1281 do_QueryInterface(supports, &rv);
1282 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"
, 1282); return rv; } } while (false)
;
1283
1284 nsCOMPtr<nsIPrincipal> principal;
1285 rv = redirectEntry->GetPrincipal(getter_AddRefs(principal));
1286 auto* basePrin = BasePrincipal::Cast(principal);
1287 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1287); return rv; } } while (false)
;
1288
1289 nsCOMPtr<nsIURI> uri;
1290 rv = basePrin->GetURI(getter_AddRefs(uri));
1291 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"
, 1291); return rv; } } while (false)
;
1292
1293 // Add the spec to our list of local lookups. The most recent redirect is
1294 // the last element.
1295 nsCString spec;
1296 rv = GetStrippedSpec(uri, spec);
1297 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"
, 1297); return rv; } } while (false)
;
1298 mBlocklistSpecs.AppendElement(spec);
1299 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)
;
1300
1301 // Store the redirect information in the remote request.
1302 ClientDownloadRequest_Resource* resource = mRequest.add_resources();
1303 resource->set_url(spec.get());
1304 resource->set_type(ClientDownloadRequest::DOWNLOAD_REDIRECT);
1305
1306 rv = iter->HasMoreElements(&hasMoreRedirects);
1307 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1307); return rv; } } while (false)
;
1308 }
1309 return NS_OK;
1310}
1311
1312nsresult PendingLookup::StartLookup() {
1313 mStartTime = TimeStamp::Now();
1314 nsresult rv = DoLookupInternal();
1315 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1316 return OnComplete(nsIApplicationReputationService::VERDICT_SAFE,
1317 Reason::eInternalerror, NS_OK);
1318 }
1319 return rv;
1320}
1321
1322nsresult PendingLookup::GetSpecHash(nsACString& aSpec,
1323 nsACString& hexEncodedHash) {
1324 nsCOMPtr<nsICryptoHash> cryptoHash;
1325 nsresult rv =
1326 NS_NewCryptoHash(nsICryptoHash::SHA256, getter_AddRefs(cryptoHash));
1327 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"
, 1327); return rv; } } while (false)
;
1328
1329 rv = cryptoHash->Update(
1330 reinterpret_cast<const uint8_t*>(aSpec.BeginReading()), aSpec.Length());
1331 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"
, 1331); return rv; } } while (false)
;
1332
1333 nsAutoCString binaryHash;
1334 rv = cryptoHash->Finish(false, binaryHash);
1335 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"
, 1335); return rv; } } while (false)
;
1336
1337 // This needs to match HexEncode() in Chrome's
1338 // src/base/strings/string_number_conversions.cc
1339 static const char* const hex = "0123456789ABCDEF";
1340 hexEncodedHash.SetCapacity(2 * binaryHash.Length());
1341 for (size_t i = 0; i < binaryHash.Length(); ++i) {
1342 auto c = static_cast<unsigned char>(binaryHash[i]);
1343 hexEncodedHash.Append(hex[(c >> 4) & 0x0F]);
1344 hexEncodedHash.Append(hex[c & 0x0F]);
1345 }
1346
1347 return NS_OK;
1348}
1349
1350nsresult PendingLookup::GetStrippedSpec(nsIURI* aUri, nsACString& escaped) {
1351 if (NS_WARN_IF(!aUri)NS_warn_if_impl(!aUri, "!aUri", "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1351)
) {
1352 return NS_ERROR_INVALID_ARG;
1353 }
1354
1355 nsresult rv;
1356 rv = aUri->GetScheme(escaped);
1357 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"
, 1357); return rv; } } while (false)
;
1358
1359 if (escaped.EqualsLiteral("blob")) {
1360 aUri->GetSpec(escaped);
1361 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)
1362 ("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)
1363 "[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)
1364 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)
;
1365 return NS_OK;
1366 }
1367
1368 if (escaped.EqualsLiteral("data")) {
1369 // Replace URI with "data:<everything before comma>,SHA256(<whole URI>)"
1370 aUri->GetSpec(escaped);
1371 int32_t comma = escaped.FindChar(',');
1372 if (comma > -1 &&
1373 static_cast<nsCString::size_type>(comma) < escaped.Length() - 1) {
1374 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"
, 1374); AnnotateMozCrashReason("MOZ_ASSERT" "(" "comma > 4"
") (" "Data URIs start with 'data:'" ")"); do { MOZ_CrashSequence
(__null, 1374); __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1375 nsAutoCString hexEncodedHash;
1376 rv = GetSpecHash(escaped, hexEncodedHash);
1377 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
1378 escaped.Truncate(comma + 1);
1379 escaped.Append(hexEncodedHash);
1380 }
1381 }
1382
1383 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)
1384 ("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)
1385 "%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)
1386 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)
;
1387 return NS_OK;
1388 }
1389
1390 // If aURI is not an nsIURL, we do not want to check the lists or send a
1391 // remote query.
1392 nsCOMPtr<nsIURL> url = do_QueryInterface(aUri, &rv);
1393 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1394 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)
1395 ("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)
1396 "= %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)
1397 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)
;
1398 return rv;
1399 }
1400
1401 nsCString temp;
1402 rv = url->GetHostPort(temp);
1403 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"
, 1403); return rv; } } while (false)
;
1404
1405 escaped.AppendLiteral("://");
1406 escaped.Append(temp);
1407
1408 rv = url->GetFilePath(temp);
1409 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"
, 1409); return rv; } } while (false)
;
1410
1411 // nsIUrl.filePath starts with '/'
1412 escaped.Append(temp);
1413
1414 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)
1415 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)
;
1416 return NS_OK;
1417}
1418
1419nsresult PendingLookup::DoLookupInternal() {
1420 // We want to check the target URI, its referrer, and associated redirects
1421 // against the local lists.
1422 nsCOMPtr<nsIURI> uri;
1423 nsresult rv = mQuery->GetSourceURI(getter_AddRefs(uri));
1424 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"
, 1424); return rv; } } while (false)
;
1425
1426 nsCString sourceSpec;
1427 rv = GetStrippedSpec(uri, sourceSpec);
1428 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"
, 1428); return rv; } } while (false)
;
1429
1430 mAnylistSpecs.AppendElement(sourceSpec);
1431
1432 ClientDownloadRequest_Resource* resource = mRequest.add_resources();
1433 resource->set_url(sourceSpec.get());
1434 resource->set_type(ClientDownloadRequest::DOWNLOAD_URL);
1435
1436 nsCOMPtr<nsIReferrerInfo> referrerInfo;
1437 (void)mQuery->GetReferrerInfo(getter_AddRefs(referrerInfo));
1438 nsCOMPtr<nsIURI> referrer;
1439 // It is quite possible that referrer header is omitted due to security reason
1440 // (for example navigation from https-> http). Hence we should use the
1441 // original referrer which has not applied referrer policy yet, to make sure
1442 // we don't mistakenly allow unsafe download.
1443 if (referrerInfo) {
1444 referrer = referrerInfo->GetOriginalReferrer();
1445 }
1446
1447 if (referrer) {
1448 nsCString referrerSpec;
1449 rv = GetStrippedSpec(referrer, referrerSpec);
1450 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"
, 1450); return rv; } } while (false)
;
1451 mBlocklistSpecs.AppendElement(referrerSpec);
1452 resource->set_referrer(referrerSpec.get());
1453 }
1454
1455 nsCOMPtr<nsIArray> redirects;
1456 rv = mQuery->GetRedirects(getter_AddRefs(redirects));
Value stored to 'rv' is never read
1457 if (redirects) {
1458 AddRedirects(redirects);
1459 } else {
1460 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)
;
1461 }
1462
1463 rv = mQuery->GetSuggestedFileName(mFileName);
1464 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !mFileName.IsEmpty()) {
1465 mIsBinaryFile = IsBinary(mFileName);
1466 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)
1467 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)
;
1468 } else {
1469 nsAutoCString errorName;
1470 mozilla::GetErrorName(rv, errorName);
1471 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)
;
1472 mFileName.Truncate();
1473 }
1474
1475 // We can skip parsing certificate for non-binary files because we only
1476 // check local block list for them.
1477 if (mIsBinaryFile) {
1478 nsTArray<nsTArray<nsTArray<uint8_t>>> sigArray;
1479 rv = mQuery->GetSignatureInfo(sigArray);
1480 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"
, 1480); return rv; } } while (false)
;
1481
1482 if (!sigArray.IsEmpty()) {
1483 rv = ParseCertificates(sigArray);
1484 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"
, 1484); return rv; } } while (false)
;
1485 }
1486
1487 rv = GenerateWhitelistStrings();
1488 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"
, 1488); return rv; } } while (false)
;
1489 }
1490
1491 // Start the call chain.
1492 return LookupNext();
1493}
1494
1495nsresult PendingLookup::OnComplete(uint32_t aVerdict, Reason aReason,
1496 nsresult aRv) {
1497 if (NS_FAILED(aRv)((bool)(__builtin_expect(!!(NS_FAILED_impl(aRv)), 0)))) {
1498 nsAutoCString errorName;
1499 mozilla::GetErrorName(aRv, errorName);
1500 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
)
1501 ("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
)
1502 "[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
)
1503 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
)
;
1504 }
1505
1506 if (mTimeoutTimer) {
1507 mTimeoutTimer->Cancel();
1508 mTimeoutTimer = nullptr;
1509 }
1510
1511 bool shouldBlock = true;
1512 switch (aVerdict) {
1513 case nsIApplicationReputationService::VERDICT_DANGEROUS:
1514 if (!Preferences::GetBool(PREF_BLOCK_DANGEROUS"browser.safebrowsing.downloads.remote.block_dangerous", true)) {
1515 shouldBlock = false;
1516 aReason = Reason::eDangerousprefoff;
1517 }
1518 break;
1519 case nsIApplicationReputationService::VERDICT_UNCOMMON:
1520 if (!Preferences::GetBool(PREF_BLOCK_UNCOMMON"browser.safebrowsing.downloads.remote.block_uncommon", true)) {
1521 shouldBlock = false;
1522 aReason = Reason::eUncommonprefoff;
1523 }
1524 break;
1525 case nsIApplicationReputationService::VERDICT_POTENTIALLY_UNWANTED:
1526 if (!Preferences::GetBool(PREF_BLOCK_POTENTIALLY_UNWANTED"browser.safebrowsing.downloads.remote.block_potentially_unwanted", true)) {
1527 shouldBlock = false;
1528 aReason = Reason::eUnwantedprefoff;
1529 }
1530 break;
1531 case nsIApplicationReputationService::VERDICT_DANGEROUS_HOST:
1532 if (!Preferences::GetBool(PREF_BLOCK_DANGEROUS_HOST"browser.safebrowsing.downloads.remote.block_dangerous_host", true)) {
1533 shouldBlock = false;
1534 aReason = Reason::eDangeroushostprefoff;
1535 }
1536 break;
1537 default:
1538 shouldBlock = false;
1539 break;
1540 }
1541
1542 mozilla::glean::application_reputation::reason.EnumGet(aReason).Add();
1543 mozilla::glean::application_reputation::should_block
1544 .EnumGet(
1545 static_cast<mozilla::glean::application_reputation::ShouldBlockLabel>(
1546 shouldBlock))
1547 .Add();
1548
1549 double t = (TimeStamp::Now() - mStartTime).ToMilliseconds();
1550 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)
1551 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)
;
1552 if (shouldBlock) {
1553 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)
1554 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)
;
1555 } else {
1556 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)
;
1557 }
1558
1559 nsresult res = mCallback->OnComplete(shouldBlock, aRv, aVerdict);
1560 return res;
1561}
1562
1563nsresult PendingLookup::ParseCertificates(
1564 const nsTArray<nsTArray<nsTArray<uint8_t>>>& aSigArray) {
1565 // Binaries may be signed by multiple chains of certificates. If there are no
1566 // chains, the binary is unsigned (or we were unable to extract signature
1567 // information on a non-Windows platform)
1568
1569 // Each chain may have multiple certificates.
1570 for (const auto& certList : aSigArray) {
1571 safe_browsing::ClientDownloadRequest_CertificateChain* certChain =
1572 mRequest.mutable_signature()->add_certificate_chain();
1573 for (const auto& cert : certList) {
1574 // Add this certificate to the protobuf to send remotely.
1575 certChain->add_element()->set_certificate(cert.Elements(), cert.Length());
1576 }
1577 }
1578 if (mRequest.signature().certificate_chain_size() > 0) {
1579 mRequest.mutable_signature()->set_trusted(true);
1580 }
1581 return NS_OK;
1582}
1583
1584nsresult PendingLookup::SendRemoteQuery() {
1585 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"
, 1587); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, std::size(ApplicationReputationService::kNonBinaryExecutables))"
")"); do { MOZ_CrashSequence(__null, 1587); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1586 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"
, 1587); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, std::size(ApplicationReputationService::kNonBinaryExecutables))"
")"); do { MOZ_CrashSequence(__null, 1587); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1587 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"
, 1587); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!IsFileType( mFileName, ApplicationReputationService::kNonBinaryExecutables, std::size(ApplicationReputationService::kNonBinaryExecutables))"
")"); do { MOZ_CrashSequence(__null, 1587); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1588 Reason reason = Reason::eNotset;
1589 nsresult rv = SendRemoteQueryInternal(reason);
1590 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1591 return OnComplete(nsIApplicationReputationService::VERDICT_SAFE, reason,
1592 rv);
1593 }
1594 // SendRemoteQueryInternal has fired off the query and we call OnComplete in
1595 // the nsIStreamListener.onStopRequest.
1596 return rv;
1597}
1598
1599nsresult PendingLookup::SendRemoteQueryInternal(Reason& aReason) {
1600 auto scopeExit = mozilla::MakeScopeExit([&aReason]() {
1601 if (aReason == Reason::eNotset) {
1602 aReason = Reason::eInternalerror;
1603 }
1604 });
1605
1606 // If we aren't supposed to do remote lookups, bail.
1607 if (!Preferences::GetBool(PREF_SB_DOWNLOADS_REMOTE_ENABLED"browser.safebrowsing.downloads.remote.enabled", false)) {
1608 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)
;
1609 aReason = Reason::eRemotelookupdisabled;
1610 return NS_ERROR_NOT_AVAILABLE;
1611 }
1612 // If the remote lookup URL is empty or absent, bail.
1613 nsString serviceUrl;
1614 nsCOMPtr<nsIURLFormatter> formatter(
1615 do_GetService("@mozilla.org/toolkit/URLFormatterService;1"));
1616 if (!formatter ||
1617 NS_FAILED(formatter->FormatURLPref(((bool)(__builtin_expect(!!(NS_FAILED_impl(formatter->FormatURLPref
( NS_ConvertASCIItoUTF16("browser.safebrowsing.downloads.remote.url"
), serviceUrl))), 0)))
1618 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)))
||
1619 serviceUrl.IsEmpty() || u"about:blank"_ns.Equals(serviceUrl)) {
1620 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)
;
1621 aReason = Reason::eRemotelookupdisabled;
1622 return NS_ERROR_NOT_AVAILABLE;
1623 }
1624
1625 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)
;
1626 // We did not find a local result, so fire off the query to the
1627 // application reputation service.
1628 nsCOMPtr<nsIURI> uri;
1629 nsresult rv;
1630 rv = mQuery->GetSourceURI(getter_AddRefs(uri));
1631 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"
, 1631); return rv; } } while (false)
;
1632 nsCString spec;
1633 rv = GetStrippedSpec(uri, spec);
1634 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"
, 1634); return rv; } } while (false)
;
1635 mRequest.set_url(spec.get());
1636
1637 uint32_t fileSize;
1638 rv = mQuery->GetFileSize(&fileSize);
1639 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"
, 1639); return rv; } } while (false)
;
1640 mRequest.set_length(fileSize);
1641 // We have no way of knowing whether or not a user initiated the
1642 // download. Set it to true to lessen the chance of false positives.
1643 mRequest.set_user_initiated(true);
1644
1645 nsCString locale;
1646 rv = LocaleService::GetInstance()->GetAppLocaleAsBCP47(locale);
1647 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"
, 1647); return rv; } } while (false)
;
1648 mRequest.set_locale(locale.get());
1649 nsCString sha256Hash;
1650 rv = mQuery->GetSha256Hash(sha256Hash);
1651 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"
, 1651); return rv; } } while (false)
;
1652 mRequest.mutable_digests()->set_sha256(
1653 std::string(sha256Hash.Data(), sha256Hash.Length()));
1654 mRequest.set_file_basename(mFileName.get());
1655 mRequest.set_download_type(GetDownloadType(mFileName));
1656
1657 if (mRequest.signature().trusted()) {
1658 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)
1659 ("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)
1660 "[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)
1661 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)
;
1662 } else {
1663 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)
1664 ("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)
1665 "[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)
1666 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)
;
1667 }
1668
1669 // Serialize the protocol buffer to a string. This can only fail if we are
1670 // out of memory, or if the protocol buffer req is missing required fields
1671 // (only the URL for now).
1672 std::string serialized;
1673 if (!mRequest.SerializeToString(&serialized)) {
1674 return NS_ERROR_UNEXPECTED;
1675 }
1676
1677 if (LOG_ENABLED()(__builtin_expect(!!(mozilla::detail::log_test(ApplicationReputationService
::prlog, mozilla::LogLevel::Debug)), 0))
) {
1678 nsAutoCString serializedStr(serialized.c_str(), serialized.length());
1679 serializedStr.ReplaceSubstring("\0"_ns, "\\0"_ns);
1680
1681 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)
1682 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)
;
1683 }
1684
1685 // Set the input stream to the serialized protocol buffer
1686 nsCOMPtr<nsIStringInputStream> sstream =
1687 do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
1688 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "./../../../../toolkit/components/reputationservice/ApplicationReputation.cpp"
, 1688); return rv; } } while (false)
;
1689
1690 rv = sstream->CopyData(serialized.c_str(), serialized.length());
1691 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"
, 1691); return rv; } } while (false)
;
1692
1693 // Set up the channel to transmit the request to the service.
1694 nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID"@mozilla.org/network/io-service;1", &rv);
1695 rv = ios->NewChannel(NS_ConvertUTF16toUTF8(serviceUrl), nullptr, nullptr,
1696 nullptr, // aLoadingNode
1697 nsContentUtils::GetSystemPrincipal(),
1698 nullptr, // aTriggeringPrincipal
1699 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
1700 nsIContentPolicy::TYPE_OTHER, getter_AddRefs(mChannel));
1701 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"
, 1701); return rv; } } while (false)
;
1702
1703 mChannel->SetLoadFlags(nsIChannel::LOAD_BYPASS_URL_CLASSIFIER);
1704
1705 nsCOMPtr<nsILoadInfo> loadInfo = mChannel->LoadInfo();
1706 mozilla::OriginAttributes attrs;
1707 attrs.mFirstPartyDomain.AssignLiteral(NECKO_SAFEBROWSING_FIRST_PARTY_DOMAIN"safebrowsing.86868755-6b82-4842-b301-72671a0db32e.mozilla");
1708 loadInfo->SetOriginAttributes(attrs);
1709
1710 nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel, &rv));
1711 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"
, 1711); return rv; } } while (false)
;
1712 (void)httpChannel;
1713
1714 // Upload the protobuf to the application reputation service.
1715 nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(mChannel, &rv);
1716 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"
, 1716); return rv; } } while (false)
;
1717
1718 rv = uploadChannel->ExplicitSetUploadStream(
1719 sstream, "application/octet-stream"_ns, serialized.size(), "POST"_ns);
1720 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"
, 1720); return rv; } } while (false)
;
1721
1722 uint32_t timeoutMs =
1723 Preferences::GetUint(PREF_SB_DOWNLOADS_REMOTE_TIMEOUT"browser.safebrowsing.downloads.remote.timeout_ms", 10000);
1724 NS_NewTimerWithCallback(getter_AddRefs(mTimeoutTimer), this, timeoutMs,
1725 nsITimer::TYPE_ONE_SHOT);
1726
1727 mTelemetryRemoteRequestStartMs = PR_IntervalNow();
1728
1729 rv = mChannel->AsyncOpen(this);
1730 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"
, 1730); return rv; } } while (false)
;
1731
1732 return NS_OK;
1733}
1734
1735NS_IMETHODIMPnsresult
1736PendingLookup::Notify(nsITimer* aTimer) {
1737 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)
;
1738 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"
, 1738); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aTimer == mTimeoutTimer"
")"); do { MOZ_CrashSequence(__null, 1738); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1739 mozilla::glean::application_reputation::remote_lookup_timeout
1740 .EnumGet(mozilla::glean::application_reputation::
1741 RemoteLookupTimeoutLabel::eTrue)
1742 .Add();
1743 mChannel->Cancel(NS_ERROR_NET_TIMEOUT_EXTERNAL);
1744 mTimeoutTimer->Cancel();
1745 return NS_OK;
1746}
1747
1748NS_IMETHODIMPnsresult
1749PendingLookup::GetName(nsACString& aName) {
1750 aName.AssignLiteral("PendingLookup");
1751 return NS_OK;
1752}
1753
1754///////////////////////////////////////////////////////////////////////////////
1755// nsIObserver implementation
1756NS_IMETHODIMPnsresult
1757PendingLookup::Observe(nsISupports* aSubject, const char* aTopic,
1758 const char16_t* aData) {
1759 if (!strcmp(aTopic, "quit-application")) {
1760 if (mTimeoutTimer) {
1761 mTimeoutTimer->Cancel();
1762 mTimeoutTimer = nullptr;
1763 }
1764 if (mChannel) {
1765 mChannel->Cancel(NS_ERROR_ABORT);
1766 }
1767 }
1768 return NS_OK;
1769}
1770
1771////////////////////////////////////////////////////////////////////////////////
1772//// nsIStreamListener
1773static nsresult AppendSegmentToString(nsIInputStream* inputStream,
1774 void* closure, const char* rawSegment,
1775 uint32_t toOffset, uint32_t count,
1776 uint32_t* writeCount) {
1777 nsAutoCString* decodedData = static_cast<nsAutoCString*>(closure);
1778 decodedData->Append(rawSegment, count);
1779 *writeCount = count;
1780 return NS_OK;
1781}
1782
1783NS_IMETHODIMPnsresult
1784PendingLookup::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aStream,
1785 uint64_t offset, uint32_t count) {
1786 uint32_t read;
1787 return aStream->ReadSegments(AppendSegmentToString, &mResponse, count, &read);
1788}
1789
1790NS_IMETHODIMPnsresult
1791PendingLookup::OnStartRequest(nsIRequest* aRequest) { return NS_OK; }
1792
1793NS_IMETHODIMPnsresult
1794PendingLookup::OnStopRequest(nsIRequest* aRequest, nsresult aResult) {
1795 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"
, 1795); return NS_ERROR_UNEXPECTED; } } while (false)
;
1796
1797 if (aResult != NS_ERROR_NET_TIMEOUT_EXTERNAL) {
1798 mozilla::glean::application_reputation::remote_lookup_timeout
1799 .EnumGet(mozilla::glean::application_reputation::
1800 RemoteLookupTimeoutLabel::eFalse)
1801 .Add();
1802
1803 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"
, 1803); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mTelemetryRemoteRequestStartMs > 0"
")"); do { MOZ_CrashSequence(__null, 1803); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1804 int32_t msecs = PR_IntervalToMilliseconds(PR_IntervalNow() -
1805 mTelemetryRemoteRequestStartMs);
1806
1807 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"
, 1807); AnnotateMozCrashReason("MOZ_ASSERT" "(" "msecs >= 0"
")"); do { MOZ_CrashSequence(__null, 1807); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1808 mozilla::glean::application_reputation::remote_lookup_response_time
1809 .AccumulateRawDuration(mozilla::TimeDuration::FromMilliseconds(msecs));
1810 }
1811
1812 uint32_t verdict = nsIApplicationReputationService::VERDICT_SAFE;
1813 Reason reason = Reason::eNotset;
1814 nsresult rv = OnStopRequestInternal(aRequest, aResult, verdict, reason);
1815 OnComplete(verdict, reason, rv);
1816 return rv;
1817}
1818
1819nsresult PendingLookup::OnStopRequestInternal(nsIRequest* aRequest,
1820 nsresult aResult,
1821 uint32_t& aVerdict,
1822 Reason& aReason) {
1823 auto scopeExit = mozilla::MakeScopeExit([&aReason]() {
1824 // If |aReason| is not set while exiting, there must be an error.
1825 if (aReason == Reason::eNotset) {
1826 aReason = Reason::eNetworkerror;
1827 }
1828 });
1829
1830 if (NS_FAILED(aResult)((bool)(__builtin_expect(!!(NS_FAILED_impl(aResult)), 0)))) {
1831 mozilla::glean::application_reputation::server.AccumulateSingleSample(
1832 SERVER_RESPONSE_FAILED);
1833 mozilla::glean::application_reputation::server_2
1834 .EnumGet(NSErrorToLabel(aResult))
1835 .Add();
1836 return aResult;
1837 }
1838
1839 nsresult rv;
1840 nsCOMPtr<nsIHttpChannel> channel = do_QueryInterface(aRequest, &rv);
1841 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1842 mozilla::glean::application_reputation::server.AccumulateSingleSample(
1843 SERVER_RESPONSE_FAILED);
1844 mozilla::glean::application_reputation::server_2
1845 .EnumGet(mozilla::glean::application_reputation::Server2Label::
1846 eFailgetchannel)
1847 .Add();
1848 return rv;
1849 }
1850
1851 uint32_t status = 0;
1852 rv = channel->GetResponseStatus(&status);
1853 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1854 mozilla::glean::application_reputation::server.AccumulateSingleSample(
1855 SERVER_RESPONSE_FAILED);
1856 mozilla::glean::application_reputation::server_2
1857 .EnumGet(mozilla::glean::application_reputation::Server2Label::
1858 eFailgetresponse)
1859 .Add();
1860 return rv;
1861 }
1862
1863 if (status != 200) {
1864 mozilla::glean::application_reputation::server.AccumulateSingleSample(
1865 SERVER_RESPONSE_FAILED);
1866 mozilla::glean::application_reputation::server_2
1867 .EnumGet(HTTPStatusToLabel(status))
1868 .Add();
1869 return NS_ERROR_NOT_AVAILABLE;
1870 }
1871
1872 std::string buf(mResponse.Data(), mResponse.Length());
1873 safe_browsing::ClientDownloadResponse response;
1874 if (!response.ParseFromString(buf)) {
1875 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)
1876 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)
;
1877 mozilla::glean::application_reputation::server.AccumulateSingleSample(
1878 SERVER_RESPONSE_INVALID);
1879 return NS_ERROR_CANNOT_CONVERT_DATA;
1880 }
1881
1882 mozilla::glean::application_reputation::server.AccumulateSingleSample(
1883 SERVER_RESPONSE_VALID);
1884 mozilla::glean::application_reputation::server_2
1885 .EnumGet(
1886 mozilla::glean::application_reputation::Server2Label::eResponsevalid)
1887 .Add();
1888
1889 // Clamp responses 0-7, we only know about 0-4 for now.
1890 mozilla::glean::application_reputation::server_verdict.AccumulateSingleSample(
1891 std::min<uint32_t>(response.verdict(), 7));
1892 const char* ext = GetFileExt(mFileName);
1893 mozilla::glean::application_reputation::server_verdict_2.Get(
1894 nsCString(ext),
1895 VerdictToLabel(std::min<uint32_t>(response.verdict(), 7)));
1896 switch (response.verdict()) {
1897 case safe_browsing::ClientDownloadResponse::DANGEROUS:
1898 aVerdict = nsIApplicationReputationService::VERDICT_DANGEROUS;
1899 aReason = Reason::eVerdictdangerous;
1900 break;
1901 case safe_browsing::ClientDownloadResponse::DANGEROUS_HOST:
1902 aVerdict = nsIApplicationReputationService::VERDICT_DANGEROUS_HOST;
1903 aReason = Reason::eVerdictdangeroushost;
1904 break;
1905 case safe_browsing::ClientDownloadResponse::POTENTIALLY_UNWANTED:
1906 aVerdict = nsIApplicationReputationService::VERDICT_POTENTIALLY_UNWANTED;
1907 aReason = Reason::eVerdictunwanted;
1908 break;
1909 case safe_browsing::ClientDownloadResponse::UNCOMMON:
1910 aVerdict = nsIApplicationReputationService::VERDICT_UNCOMMON;
1911 aReason = Reason::eVerdictuncommon;
1912 break;
1913 case safe_browsing::ClientDownloadResponse::UNKNOWN:
1914 aVerdict = nsIApplicationReputationService::VERDICT_SAFE;
1915 aReason = Reason::eVerdictunknown;
1916 break;
1917 case safe_browsing::ClientDownloadResponse::SAFE:
1918 aVerdict = nsIApplicationReputationService::VERDICT_SAFE;
1919 aReason = Reason::eVerdictsafe;
1920 break;
1921 default:
1922 // Treat everything else as safe
1923 aVerdict = nsIApplicationReputationService::VERDICT_SAFE;
1924 aReason = Reason::eVerdictunrecognized;
1925 break;
1926 }
1927
1928 return NS_OK;
1929}
1930
1931NS_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"
, 1931); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 1931
); __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"
, 1931); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"ApplicationReputationService\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 1931); __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"
, 1931); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 1931
); __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"
, 1931); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"ApplicationReputationService\" != nullptr"
") (" "Must specify a name" ")"); do { MOZ_CrashSequence(__null
, 1931); __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"
, 1931); 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; }
1932
1933ApplicationReputationService*
1934 ApplicationReputationService::gApplicationReputationService = nullptr;
1935
1936already_AddRefed<ApplicationReputationService>
1937ApplicationReputationService::GetSingleton() {
1938 if (!gApplicationReputationService) {
1939 // Note: This is cleared in the new ApplicationReputationService destructor.
1940 gApplicationReputationService = new ApplicationReputationService();
1941 }
1942 return do_AddRef(gApplicationReputationService);
1943}
1944
1945ApplicationReputationService::ApplicationReputationService() {
1946 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)
;
1947}
1948
1949ApplicationReputationService::~ApplicationReputationService() {
1950 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)
;
1951 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"
, 1951); AnnotateMozCrashReason("MOZ_ASSERT" "(" "gApplicationReputationService == this"
")"); do { MOZ_CrashSequence(__null, 1951); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1952 gApplicationReputationService = nullptr;
1953}
1954
1955NS_IMETHODIMPnsresult
1956ApplicationReputationService::QueryReputation(
1957 nsIApplicationReputationQuery* aQuery,
1958 nsIApplicationReputationCallback* aCallback) {
1959 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)
;
1960 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"
, 1960); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1961 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"
, 1961); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1962
1963 nsresult rv = QueryReputationInternal(aQuery, aCallback);
1964 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1965 Reason reason = rv == NS_ERROR_NOT_AVAILABLE ? Reason::eDpdisabled
1966 : Reason::eInternalerror;
1967
1968 mozilla::glean::application_reputation::reason.EnumGet(reason).Add();
1969 mozilla::glean::application_reputation::should_block
1970 .EnumGet(
1971 mozilla::glean::application_reputation::ShouldBlockLabel::eFalse)
1972 .Add();
1973
1974 aCallback->OnComplete(false, rv,
1975 nsIApplicationReputationService::VERDICT_SAFE);
1976 }
1977 return NS_OK;
1978}
1979
1980nsresult ApplicationReputationService::QueryReputationInternal(
1981 nsIApplicationReputationQuery* aQuery,
1982 nsIApplicationReputationCallback* aCallback) {
1983 // If malware checks aren't enabled, don't query application reputation.
1984 if (!Preferences::GetBool(PREF_SB_MALWARE_ENABLED"browser.safebrowsing.malware.enabled", false)) {
1985 return NS_ERROR_NOT_AVAILABLE;
1986 }
1987
1988 if (!Preferences::GetBool(PREF_SB_DOWNLOADS_ENABLED"browser.safebrowsing.downloads.enabled", false)) {
1989 return NS_ERROR_NOT_AVAILABLE;
1990 }
1991
1992 nsCOMPtr<nsIURI> uri;
1993 nsresult rv = aQuery->GetSourceURI(getter_AddRefs(uri));
1994 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"
, 1994); return rv; } } while (false)
;
1995 // Bail if the URI hasn't been set.
1996 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"
, 1996); return NS_ERROR_UNEXPECTED; } } while (false)
;
1997
1998 // Create a new pending lookup and start the call chain.
1999 RefPtr<PendingLookup> lookup(new PendingLookup(aQuery, aCallback));
2000
2001 // Add an observer for shutdown
2002 nsCOMPtr<nsIObserverService> observerService =
2003 mozilla::services::GetObserverService();
2004 if (!observerService) {
2005 return NS_ERROR_FAILURE;
2006 }
2007
2008 observerService->AddObserver(lookup, "quit-application", true);
2009 return lookup->StartLookup();
2010}
2011
2012nsresult ApplicationReputationService::IsBinary(const nsACString& aFileName,
2013 bool* aBinary) {
2014 *aBinary = ::IsBinary(aFileName);
2015 return NS_OK;
2016}
2017
2018nsresult ApplicationReputationService::IsExecutable(const nsACString& aFileName,
2019 bool* aExecutable) {
2020 *aExecutable =
2021 ::IsFileType(aFileName, sExecutableExts, std::size(sExecutableExts));
2022 return NS_OK;
2023}