diff options
author | Ben Kelly <wanderview@chromium.org> | 2021-01-21 17:29:38 +0000 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@qt.io> | 2021-04-20 12:56:45 +0000 |
commit | 683d6198ead9fea8e823995e87b478edc07560b5 (patch) | |
tree | 4478580525df9e8bd27a7c1a4c4d7e88340dcce4 | |
parent | 9d25daa80979aad4f7072ec3443ba806516025be (diff) |
[Backport] CVE-2021-21209: Inappropriate implementation in storage (1/5)
Cherry-pick of patch originally reviewed on
https://chromium-review.googlesource.com/c/chromium/src/+/2634124:
CacheStorage: Factor writing entry metadata into separate method.
This CL factors out the code to write an entry's metadata into its own
method. This is in preparation for a later CL that will need to rewrite
the metadata with an updated value.
Bug: 1143526
Change-Id: I887bbd5f631e41c19c1e863c04d531764de807c9
Commit-Queue: Ben Kelly <wanderview@chromium.org>
Reviewed-by: Marijn Kruisselbrink <mek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#845689}
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r-- | chromium/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc | 63 | ||||
-rw-r--r-- | chromium/content/browser/cache_storage/legacy/legacy_cache_storage_cache.h | 7 |
2 files changed, 43 insertions, 27 deletions
diff --git a/chromium/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc b/chromium/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc index 2d2aae6481f..c662b8af907 100644 --- a/chromium/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc +++ b/chromium/content/browser/cache_storage/legacy/legacy_cache_storage_cache.cc @@ -1458,6 +1458,38 @@ void LegacyCacheStorageCache::MatchAllDidQueryCache( std::move(out_responses)); } +void LegacyCacheStorageCache::WriteMetadata( + disk_cache::Entry* entry, + const proto::CacheMetadata& metadata, + WriteMetadataCallback callback) { + std::unique_ptr<std::string> serialized = std::make_unique<std::string>(); + if (!metadata.SerializeToString(serialized.get())) { + std::move(callback).Run(0, -1); + return; + } + + scoped_refptr<net::StringIOBuffer> buffer = + base::MakeRefCounted<net::StringIOBuffer>(std::move(serialized)); + + auto callback_with_expected_bytes = base::BindOnce( + [](WriteMetadataCallback callback, int expected_bytes, int rv) { + std::move(callback).Run(expected_bytes, rv); + }, + std::move(callback), buffer->size()); + + // Create a callback that is copyable, even though it can only be called once. + net::CompletionRepeatingCallback adapted_callback = + base::AdaptCallbackForRepeating(std::move(callback_with_expected_bytes)); + + DCHECK(scheduler_->IsRunningExclusiveOperation()); + int rv = + entry->WriteData(INDEX_HEADERS, /*offset=*/0, buffer.get(), + buffer->size(), adapted_callback, /*truncate=*/true); + + if (rv != net::ERR_IO_PENDING) + std::move(adapted_callback).Run(rv); +} + void LegacyCacheStorageCache::WriteSideDataDidGetQuota( ErrorCallback callback, const GURL& url, @@ -1838,36 +1870,13 @@ void LegacyCacheStorageCache::PutDidCreateEntry( for (const auto& header : put_context->response->cors_exposed_header_names) response_metadata->add_cors_exposed_header_names(header); - std::unique_ptr<std::string> serialized(new std::string()); - if (!metadata.SerializeToString(serialized.get())) { - PutComplete( - std::move(put_context), - MakeErrorStorage(ErrorStorageType::kMetadataSerializationFailed)); - return; - } - - scoped_refptr<net::StringIOBuffer> buffer = - base::MakeRefCounted<net::StringIOBuffer>(std::move(serialized)); - // Get a temporary copy of the entry pointer before passing it in base::Bind. disk_cache::Entry* temp_entry_ptr = put_context->cache_entry.get(); - // Create a callback that is copyable, even though it can only be called once. - // BindRepeating() cannot be used directly because |put_context| is not - // copyable. - net::CompletionRepeatingCallback write_headers_callback = - base::AdaptCallbackForRepeating( - base::BindOnce(&LegacyCacheStorageCache::PutDidWriteHeaders, - weak_ptr_factory_.GetWeakPtr(), std::move(put_context), - buffer->size())); - - DCHECK(scheduler_->IsRunningExclusiveOperation()); - rv = temp_entry_ptr->WriteData(INDEX_HEADERS, 0 /* offset */, buffer.get(), - buffer->size(), write_headers_callback, - true /* truncate */); - - if (rv != net::ERR_IO_PENDING) - std::move(write_headers_callback).Run(rv); + WriteMetadata( + temp_entry_ptr, metadata, + base::BindOnce(&LegacyCacheStorageCache::PutDidWriteHeaders, + weak_ptr_factory_.GetWeakPtr(), std::move(put_context))); } void LegacyCacheStorageCache::PutDidWriteHeaders( diff --git a/chromium/content/browser/cache_storage/legacy/legacy_cache_storage_cache.h b/chromium/content/browser/cache_storage/legacy/legacy_cache_storage_cache.h index 659ed7ce3e1..a2b541a5293 100644 --- a/chromium/content/browser/cache_storage/legacy/legacy_cache_storage_cache.h +++ b/chromium/content/browser/cache_storage/legacy/legacy_cache_storage_cache.h @@ -306,6 +306,13 @@ class CONTENT_EXPORT LegacyCacheStorageCache : public CacheStorageCache { blink::mojom::CacheStorageError error, std::unique_ptr<QueryCacheResults> query_cache_results); + // Utility method to write metadata headers to an entry. + using WriteMetadataCallback = + base::OnceCallback<void(int exepected_bytes, int rv)>; + void WriteMetadata(disk_cache::Entry* entry, + const proto::CacheMetadata& metadata, + WriteMetadataCallback callback); + // WriteSideData callbacks void WriteSideDataDidGetQuota(ErrorCallback callback, const GURL& url, |