xref: /aosp_15_r20/external/cronet/testing/libfuzzer/fuzzers/skia_image_filter_proto_fuzzer.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2018 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Takes an Input protobuf message from libprotobuf-mutator, converts it to an
6 // actual skia image filter and then applies it to a canvas for the purpose of
7 // fuzzing skia. This should uncover bugs that could be used by a compromised
8 // renderer to exploit the browser process.
9 
10 #include <stdlib.h>
11 
12 #include <iostream>
13 #include <string>
14 
15 #include "testing/libfuzzer/proto/skia_image_filter_proto_converter.h"
16 
17 #include "base/memory/raw_ptr.h"
18 #include "base/process/memory.h"
19 #include "base/test/test_discardable_memory_allocator.h"
20 #include "third_party/libprotobuf-mutator/src/src/libfuzzer/libfuzzer_macro.h"
21 #include "third_party/skia/include/core/SkBitmap.h"
22 #include "third_party/skia/include/core/SkCanvas.h"
23 #include "third_party/skia/include/core/SkImage.h"
24 #include "third_party/skia/include/core/SkImageFilter.h"
25 
26 protobuf_mutator::protobuf::LogSilencer log_silencer;
27 
28 using skia_image_filter_proto_converter::Input;
29 using skia_image_filter_proto_converter::Converter;
30 
31 static const int kBitmapSize = 24;
32 
33 struct Environment {
34   raw_ptr<base::TestDiscardableMemoryAllocator> discardable_memory_allocator;
EnvironmentEnvironment35   Environment() {
36     base::EnableTerminationOnOutOfMemory();
37     discardable_memory_allocator = new base::TestDiscardableMemoryAllocator();
38     base::DiscardableMemoryAllocator::SetInstance(discardable_memory_allocator);
39   }
40 };
41 
DEFINE_PROTO_FUZZER(const Input & input)42 DEFINE_PROTO_FUZZER(const Input& input) {
43   [[maybe_unused]] static Environment environment = Environment();
44 
45   static Converter converter = Converter();
46   std::string ipc_filter_message = converter.Convert(input);
47 
48   // Allow the flattened skia filter to be retrieved easily.
49   if (getenv("LPM_DUMP_NATIVE_INPUT")) {
50     // Don't write a newline since it will make the output invalid (so that it
51     // cannot be fed to filter_fuzz_stub) Flush instead.
52     std::cout << ipc_filter_message << std::flush;
53   }
54 
55   sk_sp<SkImageFilter> flattenable = SkImageFilter::Deserialize(
56       ipc_filter_message.c_str(), ipc_filter_message.size());
57 
58   if (!flattenable)
59     return;
60 
61   SkBitmap bitmap;
62   bitmap.allocN32Pixels(kBitmapSize, kBitmapSize);
63   SkCanvas canvas(bitmap);
64   canvas.clear(0x00000000);
65   SkPaint paint;
66   paint.setImageFilter(flattenable);
67   canvas.save();
68   canvas.clipRect(SkRect::MakeXYWH(0, 0, SkIntToScalar(kBitmapSize),
69                                    SkIntToScalar(kBitmapSize)));
70   canvas.drawImage(bitmap.asImage(), 0, 0, SkSamplingOptions(), &paint);
71   canvas.restore();
72 }
73