summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Kelly <wanderview@chromium.org>2021-01-21 17:29:38 +0000
committerMichael BrĂ¼ning <michael.bruning@qt.io>2021-04-20 12:56:45 +0000
commit683d6198ead9fea8e823995e87b478edc07560b5 (patch)
tree4478580525df9e8bd27a7c1a4c4d7e88340dcce4
parent9d25daa80979aad4f7072ec3443ba806516025be (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.cc63
-rw-r--r--chromium/content/browser/cache_storage/legacy/legacy_cache_storage_cache.h7
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,