Commit b346beb3 authored by Adrienne Walker's avatar Adrienne Walker Committed by Commit Bot

oop: Add transfer cache deserialization fuzzer

Bug: 804301
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: I3b063e13c7b08b28d3973d1b16a2633101135fa6
Reviewed-on: https://chromium-review.googlesource.com/947046Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Reviewed-by: default avatarEric Karl <ericrk@chromium.org>
Reviewed-by: default avatarKhushal <khushalsagar@chromium.org>
Commit-Queue: enne <enne@chromium.org>
Cr-Commit-Position: refs/heads/master@{#541286}
parent 69c09e03
......@@ -134,3 +134,17 @@ fuzzer_test("paint_op_buffer_eq_fuzzer") {
"//cc/paint",
]
}
fuzzer_test("transfer_cache_fuzzer") {
sources = [
"transfer_cache_fuzzer.cc",
]
libfuzzer_options = [ "max_len=4096" ]
deps = [
"//cc:test_support",
"//cc/paint",
"//components/viz/test:test_support",
]
}
......@@ -2,4 +2,7 @@ specific_include_rules = {
"paint_op_buffer_fuzzer.cc": [
"+components/viz/test",
],
"transfer_cache_fuzzer.cc": [
"+components/viz/test",
],
}
......@@ -46,8 +46,8 @@ size_t ServiceColorSpaceTransferCacheEntry::CachedSize() const {
bool ServiceColorSpaceTransferCacheEntry::Deserialize(
GrContext* context,
base::span<uint8_t> data) {
base::Pickle pickle(reinterpret_cast<char*>(data.data()), data.size());
base::span<const uint8_t> data) {
base::Pickle pickle(reinterpret_cast<const char*>(data.data()), data.size());
base::PickleIterator iterator(pickle);
if (!IPC::ParamTraits<gfx::ColorSpace>::Read(&pickle, &iterator,
&color_space_))
......
......@@ -44,7 +44,7 @@ class CC_PAINT_EXPORT ServiceColorSpaceTransferCacheEntry final
ServiceColorSpaceTransferCacheEntry();
~ServiceColorSpaceTransferCacheEntry() override;
size_t CachedSize() const override;
bool Deserialize(GrContext* context, base::span<uint8_t> data) override;
bool Deserialize(GrContext* context, base::span<const uint8_t> data) override;
const gfx::ColorSpace& color_space() const { return color_space_; }
......
......@@ -87,8 +87,9 @@ size_t ServiceImageTransferCacheEntry::CachedSize() const {
return size_;
}
bool ServiceImageTransferCacheEntry::Deserialize(GrContext* context,
base::span<uint8_t> data) {
bool ServiceImageTransferCacheEntry::Deserialize(
GrContext* context,
base::span<const uint8_t> data) {
PaintOpReader reader(data.data(), data.size(), nullptr);
SkColorType color_type;
reader.Read(&color_type);
......@@ -109,6 +110,8 @@ bool ServiceImageTransferCacheEntry::Deserialize(GrContext* context,
SkImageInfo image_info = SkImageInfo::Make(
width, height, color_type, kPremul_SkAlphaType, pixmap_color_space);
if (image_info.computeMinByteSize() > pixel_size)
return false;
const volatile void* pixel_data = reader.ExtractReadableMemory(pixel_size);
if (!reader.valid())
return false;
......
......@@ -54,7 +54,7 @@ class CC_PAINT_EXPORT ServiceImageTransferCacheEntry
// ServiceTransferCacheEntry implementation:
size_t CachedSize() const final;
bool Deserialize(GrContext* context, base::span<uint8_t> data) final;
bool Deserialize(GrContext* context, base::span<const uint8_t> data) final;
void set_image_for_testing(sk_sp<SkImage> image) {
image_ = std::move(image);
......
......@@ -118,7 +118,7 @@ size_t ServicePaintTypefaceTransferCacheEntry::CachedSize() const {
bool ServicePaintTypefaceTransferCacheEntry::Deserialize(
GrContext* context,
base::span<uint8_t> data) {
base::span<const uint8_t> data) {
data_ = data;
size_t initial_size = data_.size();
......@@ -208,7 +208,7 @@ void ServicePaintTypefaceTransferCacheEntry::ReadSimple(T* val) {
valid_ = false;
if (!valid_)
return;
*val = *reinterpret_cast<T*>(data_.data());
*val = *reinterpret_cast<const T*>(data_.data());
data_ = data_.subspan(sizeof(T));
}
......
......@@ -37,7 +37,7 @@ class CC_PAINT_EXPORT ServicePaintTypefaceTransferCacheEntry
ServicePaintTypefaceTransferCacheEntry();
~ServicePaintTypefaceTransferCacheEntry() final;
size_t CachedSize() const final;
bool Deserialize(GrContext* context, base::span<uint8_t> data) final;
bool Deserialize(GrContext* context, base::span<const uint8_t> data) final;
const PaintTypeface& typeface() const { return typeface_; }
......@@ -50,7 +50,9 @@ class CC_PAINT_EXPORT ServicePaintTypefaceTransferCacheEntry
PaintTypeface typeface_;
size_t size_ = 0;
bool valid_ = true;
base::span<uint8_t> data_;
// TODO(enne): this transient value shouldn't be a member and should just be
// passed around internally to functions that need it.
base::span<const uint8_t> data_;
};
} // namespace cc
......
......@@ -43,8 +43,9 @@ size_t ServiceRawMemoryTransferCacheEntry::CachedSize() const {
return data_.size();
}
bool ServiceRawMemoryTransferCacheEntry::Deserialize(GrContext* context,
base::span<uint8_t> data) {
bool ServiceRawMemoryTransferCacheEntry::Deserialize(
GrContext* context,
base::span<const uint8_t> data) {
data_ = std::vector<uint8_t>(data.begin(), data.end());
return true;
}
......
......@@ -37,7 +37,7 @@ class CC_PAINT_EXPORT ServiceRawMemoryTransferCacheEntry
ServiceRawMemoryTransferCacheEntry();
~ServiceRawMemoryTransferCacheEntry() final;
size_t CachedSize() const final;
bool Deserialize(GrContext* context, base::span<uint8_t> data) final;
bool Deserialize(GrContext* context, base::span<const uint8_t> data) final;
const std::vector<uint8_t>& data() { return data_; }
private:
......
......@@ -27,7 +27,6 @@ std::unique_ptr<ServiceTransferCacheEntry> ServiceTransferCacheEntry::Create(
return std::make_unique<ServiceColorSpaceTransferCacheEntry>();
}
NOTREACHED();
return nullptr;
}
......
......@@ -82,7 +82,8 @@ class CC_PAINT_EXPORT ServiceTransferCacheEntry {
// Deserialize the cache entry from the given span of memory with the given
// context.
virtual bool Deserialize(GrContext* context, base::span<uint8_t> data) = 0;
virtual bool Deserialize(GrContext* context,
base::span<const uint8_t> data) = 0;
};
// Helpers to simplify subclassing.
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stddef.h>
#include <stdint.h>
#include "cc/paint/paint_op_buffer.h"
#include "cc/paint/raw_memory_transfer_cache_entry.h"
#include "cc/test/transfer_cache_test_helper.h"
#include "components/viz/test/test_context_provider.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrContext.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if (size < 4)
return 0;
scoped_refptr<viz::TestContextProvider> context_provider =
viz::TestContextProvider::Create();
context_provider->BindToCurrentThread();
cc::TransferCacheEntryType entry_type =
static_cast<cc::TransferCacheEntryType>(data[0]);
std::unique_ptr<cc::ServiceTransferCacheEntry> entry =
cc::ServiceTransferCacheEntry::Create(entry_type);
if (!entry)
return 0;
// Align data.
base::span<const uint8_t> span(&data[4], size - 4);
if (!entry->Deserialize(context_provider->GrContext(), span))
return 0;
// TODO(enne): consider running Serialize() here to fuzz that codepath
// for bugs. However, that requires setting up a real context with
// a raster interface that supports gl operations and that has a
// TransferCacheTestHelper in it so the innards of client and service
// are accessible.
return 0;
}
......@@ -46,16 +46,17 @@ bool ServiceTransferCache::CreateLockedEntry(
base::span<uint8_t> data) {
auto key = std::make_pair(entry_type, entry_id);
auto found = entries_.Peek(key);
if (found != entries_.end()) {
if (found != entries_.end())
return false;
}
std::unique_ptr<cc::ServiceTransferCacheEntry> entry =
cc::ServiceTransferCacheEntry::Create(entry_type);
if (!entry)
return false;
entry->Deserialize(context, data);
if (!entry->Deserialize(context, data))
return false;
total_size_ += entry->CachedSize();
entries_.Put(key, CacheEntryInternal(handle, std::move(entry)));
EnforceLimits();
......
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