Bug Summary

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