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