Integer Overflow in Chrome safe browsing
Reported by
wykcompu...@gmail.com,
Feb 24 2017
|
||||||||
Issue descriptionUserAgent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 Steps to reproduce the problem: 1.Replace the "C:\Users\xxx\AppData\Local\Google\Chrome\User Data\Safe Browsing Bloom Prefix Set" with the PoC file. 2.Trun to Safe browsing mode in Chrome. What is the expected behavior? The Browser Process(main process) of Chrome will crash. The Chrome app can not be reopened. What went wrong? When go to Safe browsing mode,Chrome will call PrefixSet::LoadFile function in src/components/safe_browsing_db/prefix_set.cc. ref:https://cs.chromium.org/chromium/src/components/safe_browsing_db/prefix_set.cc?q=src/components/safe_browsing_db/prefix_set.cc+package:%5Echromium$ACTUALl=164 In PrefixSet::LoadFile, it will open "Safe Browsing Bloom Prefix Set" file, then read something. First, read Header: 177 FileHeader header; 178 size_t read = fread(&header, sizeof(header), 1, file.get()); Then compute index_bytes, deltas_bytes, full_hashes_bytes: 200 IndexVector index; 201 const size_t index_bytes = sizeof(index[0]) * header.index_size; 203 std::vector<uint16_t> deltas; 204 const size_t deltas_bytes = sizeof(deltas[0]) * header.deltas_size; 206 std::vector<SBFullHash> full_hashes; 207 const size_t full_hashes_bytes = sizeof(full_hashes[0]) * header.full_hashes_size; Then compute expected_bytes, and do saint check to avoid overflow: 210 // Check for bogus sizes before allocating any space. 211 const size_t expected_bytes = sizeof(header) + 212 index_bytes + deltas_bytes + full_hashes_bytes + sizeof(MD5Digest); 213 if (static_cast<int64_t>(expected_bytes) != size_64) 214 return nullptr; But the check is invalid on 32-bits platform, because expected_bytes with type size_t is 32 bits, it will also overflow when index_bytes, deltas_bytes or full_hashes_bytes is large enough. And the index_bytes, deltas_bytes or full_hashes_bytes is computed with value from "Safe Browsing Bloom Prefix Set" file. By bypassing the integer overflow, the program can go on, leading to crash, such as: 220 index.resize(header.index_size); 231 deltas.resize(header.deltas_size); 242 full_hashes.resize(header.full_hashes_size); Patch: To avoid the cash, just modify "const size_t expected_bytes" to "const int64_t expected_bytes". Did this work before? N/A Chrome version: 56.0.2924.87 Channel: stable OS Version: 6.1 (Windows 7, Windows Server 2008 R2) Flash Version:
,
Feb 27 2017
Just click to go to incognito mode in the upper right corner.
,
Mar 2 2017
FYI the code that reads that file will be removed in about a month when we switch to Pver4 db updates. Also, this isn't a security issue since it requires local write access to files. It's possibly a functional bug, which would cause a crash loop if the file were corrupted in just the wrong way. But it's probably not worth fixing at this point. +vakh to decide
,
Mar 2 2017
Thank you for providing more feedback. Adding requester "kerrnel@chromium.org" to the cc list and removing "Needs-Feedback" label. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Mar 2 2017
Thanks for reporting this issue. kerrnel@: Re #c1: You need a 32-bit machine to reproduce it which may be why you weren't able to reproduce this. I haven't tried to reproduce it myself but I don't think there's much value in fixing this now because: 1. It requires file system access (or tricking the user to download an attacker crafted file in Chrome's profile directory with a specific name), AND 2. This code will be turned off within a month since we are already running its replacement, PVer4, in Stable and plan to push it to 100% within 2 weeks or so. Marking it as blocked on the PVer4 launch bug.
,
Mar 2 2017
Ha, great! If I get this right, the gist of it is that the header tells it that there's enough data that the actual file size matches the overflowed estimated size? So it would have to be about 2^32 of data. On a 32-bit platform, a 2^32 allocation is going to fail with a forced OOM every time, which is safe. In fact, I think the boundary is either 2G or 3G, so I think this case is guaranteed to crash in a safe manner. [By "safe" I mean "May be annoying, but I don't think it can be used to attack anything."] It might be worthwhile to check the crash server to see if the indicated crashes are happening, though. Though I guess there's no action item for it, so maybe not worthwhile.
,
Mar 10 2017
,
Mar 15 2017
,
Mar 24 2017
Closing because it requires specific intentional modification of a local file, and is in obsolete code.
,
Aug 10 2017
|
||||||||
►
Sign in to add a comment |
||||||||
Comment 1 by kerrnel@chromium.org
, Feb 24 2017Labels: Needs-Feedback