Bug Summary

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