Bug 308713
| Summary: | Integer overflow in IndexedDB string key length bypasses bounds check | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | Jarred Sumner <jarred> |
| Component: | WebCore Misc. | Assignee: | Anne van Kesteren <annevk> |
| Status: | RESOLVED FIXED | ||
| Severity: | Normal | CC: | annevk, bfulgham, k_monsen, simon.fraser, webkit-bug-importer, ysuzuki |
| Priority: | P2 | Keywords: | InRadar |
| Version: | WebKit Nightly Build | ||
| Hardware: | Unspecified | ||
| OS: | Unspecified | ||
Jarred Sumner
I found this via Claude Code Security. Please don't credit me personally.
SUMMARY
In the string key deserialization path of decodeKey() at Source/WebCore/Modules/indexeddb/server/IDBSerialization.cpp:326, the bounds check data.size() < length * 2 uses 32-bit unsigned arithmetic for the multiplication (length is uint32_t). When length >= 0x80000000, length * 2 wraps to a small value, bypassing the check. The subsequent reserveInitialCapacity(length) attempts to allocate ~4GB, causing an OOM crash.
DETAILS
At IDBSerialization.cpp:321-330:
case SIDBKeyType::String: {
uint32_t length;
if (!readLittleEndian(data, length))
return false;
if (data.size() < length * 2) // uint32_t * 2 overflows
return false;
Vector<char16_t> buffer;
buffer.reserveInitialCapacity(length); // tries to reserve ~2GB+ entries
For example, length=0x80000000 gives length*2=0 (wrap), so data.size() < 0 is always false, and the check passes. The binary key case (nearby code) correctly uses uint64_t for its size field and has a separate > std::numeric_limits<size_t>::max() check, confirming this string case is missing equivalent protection.
SUGGESTED FIX
Cast length to size_t before multiplying: if (data.size() < static_cast<size_t>(length) * 2).
| Attachments | ||
|---|---|---|
| Add attachment proposed patch, testcase, etc. |
Radar WebKit Bug Importer
<rdar://problem/171245941>
Anne van Kesteren
https://github.com/WebKit/WebKit/pull/59885
EWS
Committed 308649@main (e5eb16d1eda3): <https://commits.webkit.org/308649@main>
Reviewed commits have been landed. Closing PR #59885 and removing active labels.