Commit d9207bf9 authored by Chase Phillips's avatar Chase Phillips Committed by Commit Bot

IndexedDB: Stricter put size checks

IndexedDB's Put() call from the renderer runs across a Mojo
interface.  The args to the interface call are serialized by Mojo
and then received by the browser process.

Users can submit args to the call that are arbitrary in size.  If the
args are too large, Mojo will detect the message is too large to
send to the browser process and will crash the renderer.

To avoid the crash, we first check the size of the args before
calling the interface method.  Previously, this check only looked
at the value and key args.  Extend the check to also look at the
index_keys arg, which could also be arbitrarily large.

Bug: 901269
Bug: 717812
Change-Id: Ifb67c8c72f2db37a412c6583d8418454dbc85713
Reviewed-on: https://chromium-review.googlesource.com/c/1325078Reviewed-by: default avatarDaniel Murphy <dmurph@chromium.org>
Commit-Queue: Chase Phillips <cmp@chromium.org>
Cr-Commit-Position: refs/heads/master@{#606301}
parent d77b3b7c
......@@ -171,18 +171,8 @@ void WebIDBDatabaseImpl::Put(
WebIDBKeyView web_primary_key,
blink::WebIDBPutMode put_mode,
WebIDBCallbacks* callbacks,
const WebVector<blink::WebIDBIndexKeys>& index_keys) {
IndexedDBKey key = IndexedDBKeyBuilder::Build(web_primary_key);
if (value.size() + key.size_estimate() > max_put_value_size_) {
callbacks->OnError(blink::WebIDBDatabaseError(
blink::kWebIDBDatabaseExceptionUnknownError,
WebString::FromUTF8(base::StringPrintf(
"The serialized value is too large"
" (size=%" PRIuS " bytes, max=%" PRIuS " bytes).",
value.size(), max_put_value_size_))));
return;
}
const WebVector<blink::WebIDBIndexKeys>& web_index_keys) {
IndexedDBKey primary_key = IndexedDBKeyBuilder::Build(web_primary_key);
IndexedDBDispatcher::ThreadSpecificInstance()->ResetCursorPrefetchCaches(
transaction_id, nullptr);
......@@ -218,10 +208,32 @@ void WebIDBDatabaseImpl::Put(
mojo_value->blob_or_file_info.push_back(std::move(blob_info));
}
std::vector<blink::IndexedDBIndexKeys> index_keys =
ConvertWebIndexKeys(web_index_keys);
size_t index_keys_size = 0;
for (const auto& index_key : index_keys) {
index_keys_size++; // Account for index_key.first (int64_t).
for (const auto& key : index_key.second) {
index_keys_size += key.size_estimate();
}
}
size_t arg_size =
mojo_value->bits.size() + primary_key.size_estimate() + index_keys_size;
if (arg_size >= max_put_value_size_) {
callbacks->OnError(blink::WebIDBDatabaseError(
blink::kWebIDBDatabaseExceptionUnknownError,
WebString::FromUTF8(base::StringPrintf(
"The serialized keys and/or value are too large"
" (size=%" PRIuS " bytes, max=%" PRIuS " bytes).",
arg_size, max_put_value_size_))));
return;
}
auto callbacks_impl = std::make_unique<IndexedDBCallbacksImpl>(
base::WrapUnique(callbacks), transaction_id, nullptr);
database_->Put(transaction_id, object_store_id, std::move(mojo_value), key,
put_mode, ConvertWebIndexKeys(index_keys),
database_->Put(transaction_id, object_store_id, std::move(mojo_value),
primary_key, put_mode, std::move(index_keys),
GetCallbacksProxy(std::move(callbacks_impl)));
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment