Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/toolkit/components/reputationservice/ApplicationReputation.cpp
Warning:line 1436, column 3
Value stored to 'rv' is never read

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