blob: 9ca5430e472c8337f6ee51b371be4d0ba649f798 [file] [log] [blame]
Florian Mayer60d1e132018-01-26 15:00:52 +00001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stddef.h>
18#include <stdint.h>
19#include <unistd.h>
20
21#include "perfetto/base/logging.h"
22#include "perfetto/base/task_runner.h"
23#include "perfetto/base/utils.h"
24#include "perfetto/ipc/host.h"
Hector Dearmanfaa22f82018-02-14 12:02:51 +000025#include "perfetto/trace/test_event.pbzero.h"
Lalit Magantic4c3ceb2018-03-29 20:38:13 +010026#include "perfetto/traced/traced.h"
Florian Mayer60d1e132018-01-26 15:00:52 +000027#include "perfetto/tracing/core/data_source_config.h"
28#include "perfetto/tracing/core/data_source_descriptor.h"
29#include "perfetto/tracing/core/producer.h"
30#include "perfetto/tracing/core/trace_writer.h"
31#include "perfetto/tracing/ipc/producer_ipc_client.h"
32#include "perfetto/tracing/ipc/service_ipc_host.h"
33#include "src/base/test/test_task_runner.h"
Florian Mayerc29e0d32018-04-04 15:55:46 +010034#include "src/tracing/ipc/default_socket.h"
Florian Mayer60d1e132018-01-26 15:00:52 +000035#include "test/task_runner_thread.h"
Lalit Magantibfc3d3e2018-03-22 20:28:38 +000036#include "test/task_runner_thread_delegates.h"
Lalit Magantic4c3ceb2018-03-29 20:38:13 +010037#include "test/test_helper.h"
Florian Mayer60d1e132018-01-26 15:00:52 +000038
Primiano Tucci07e104d2018-04-03 20:45:35 +020039#include "perfetto/trace/trace_packet.pb.h"
40#include "perfetto/trace/trace_packet.pbzero.h"
41
Florian Mayer60d1e132018-01-26 15:00:52 +000042namespace perfetto {
43namespace shm_fuzz {
44
Lalit Magantic4c3ceb2018-03-29 20:38:13 +010045// If we're building on Android and starting the daemons ourselves,
46// create the sockets in a world-writable location.
47#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
48 PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
49#define TEST_PRODUCER_SOCK_NAME "/data/local/tmp/traced_producer"
50#else
Florian Mayerc29e0d32018-04-04 15:55:46 +010051#define TEST_PRODUCER_SOCK_NAME ::perfetto::GetProducerSocket()
Lalit Magantic4c3ceb2018-03-29 20:38:13 +010052#endif
Florian Mayer43374ba2018-02-16 13:35:16 +000053
Florian Mayer60d1e132018-01-26 15:00:52 +000054// Fake producer writing a protozero message of data into shared memory
55// buffer, followed by a sentinel message to signal completion to the
56// consumer.
57class FakeProducer : public Producer {
58 public:
Florian Mayer20c2c722018-02-15 14:10:16 +000059 FakeProducer(std::string name,
60 const uint8_t* data,
61 size_t size,
Lalit Magantidd95ef92018-03-23 09:42:48 +000062 std::function<void()> on_produced_and_committed)
63 : name_(std::move(name)),
64 data_(data),
65 size_(size),
66 on_produced_and_committed_(on_produced_and_committed) {}
Florian Mayer60d1e132018-01-26 15:00:52 +000067
68 void Connect(const char* socket_name, base::TaskRunner* task_runner) {
Lalit Maganti8f47a5b2018-03-28 20:50:28 +010069 endpoint_ = ProducerIPCClient::Connect(
70 socket_name, this, "android.perfetto.FakeProducer", task_runner);
Florian Mayer60d1e132018-01-26 15:00:52 +000071 }
72
73 void OnConnect() override {
74 DataSourceDescriptor descriptor;
75 descriptor.set_name(name_);
Lalit Maganti79a69912018-03-29 17:32:29 +010076 endpoint_->RegisterDataSource(descriptor);
Florian Mayer60d1e132018-01-26 15:00:52 +000077 }
78
79 void OnDisconnect() override {}
80
81 void CreateDataSourceInstance(
82 DataSourceInstanceID,
83 const DataSourceConfig& source_config) override {
Lalit Magantidd95ef92018-03-23 09:42:48 +000084 auto trace_writer = endpoint_->CreateTraceWriter(
85 static_cast<BufferID>(source_config.target_buffer()));
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000086 {
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000087 auto packet = trace_writer->NewTracePacket();
88 packet->stream_writer_->WriteBytes(data_, size_);
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000089 }
Lalit Magantidd95ef92018-03-23 09:42:48 +000090 trace_writer->Flush();
91
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000092 {
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000093 auto end_packet = trace_writer->NewTracePacket();
94 end_packet->set_for_testing()->set_str("end");
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000095 }
Lalit Magantidd95ef92018-03-23 09:42:48 +000096 trace_writer->Flush(on_produced_and_committed_);
Florian Mayer60d1e132018-01-26 15:00:52 +000097 }
98
99 void TearDownDataSourceInstance(DataSourceInstanceID) override {}
Primiano Tuccidca727d2018-04-04 11:31:55 +0200100 void OnTracingSetup() override {}
Florian Mayer60d1e132018-01-26 15:00:52 +0000101
102 private:
103 const std::string name_;
104 const uint8_t* data_;
105 const size_t size_;
Florian Mayer60d1e132018-01-26 15:00:52 +0000106 std::unique_ptr<Service::ProducerEndpoint> endpoint_;
Lalit Magantidd95ef92018-03-23 09:42:48 +0000107 std::function<void()> on_produced_and_committed_;
Florian Mayer60d1e132018-01-26 15:00:52 +0000108};
109
110class FakeProducerDelegate : public ThreadDelegate {
111 public:
Lalit Magantidd95ef92018-03-23 09:42:48 +0000112 FakeProducerDelegate(const uint8_t* data,
113 size_t size,
114 std::function<void()> on_produced_and_committed)
115 : data_(data),
116 size_(size),
117 on_produced_and_committed_(on_produced_and_committed) {}
Florian Mayer60d1e132018-01-26 15:00:52 +0000118 ~FakeProducerDelegate() override = default;
119
120 void Initialize(base::TaskRunner* task_runner) override {
Florian Mayer20c2c722018-02-15 14:10:16 +0000121 producer_.reset(new FakeProducer("android.perfetto.FakeProducer", data_,
Lalit Magantidd95ef92018-03-23 09:42:48 +0000122 size_, on_produced_and_committed_));
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100123 producer_->Connect(TEST_PRODUCER_SOCK_NAME, task_runner);
Florian Mayer60d1e132018-01-26 15:00:52 +0000124 }
125
126 private:
127 std::unique_ptr<FakeProducer> producer_;
128 const uint8_t* data_;
129 const size_t size_;
Lalit Magantidd95ef92018-03-23 09:42:48 +0000130 std::function<void()> on_produced_and_committed_;
Florian Mayer60d1e132018-01-26 15:00:52 +0000131};
132
Florian Mayer60d1e132018-01-26 15:00:52 +0000133int FuzzSharedMemory(const uint8_t* data, size_t size);
134
135int FuzzSharedMemory(const uint8_t* data, size_t size) {
Lalit Magantidd95ef92018-03-23 09:42:48 +0000136 base::TestTaskRunner task_runner;
137
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100138 TestHelper helper(&task_runner);
139 helper.StartServiceIfRequired();
Florian Mayer60d1e132018-01-26 15:00:52 +0000140
Lalit Magantidd95ef92018-03-23 09:42:48 +0000141 auto on_produced_and_committed =
142 task_runner.CreateCheckpoint("produced.and.committed");
143 auto posted_on_produced_and_committed = [&task_runner,
144 &on_produced_and_committed] {
145 task_runner.PostTask(on_produced_and_committed);
146 };
147 TaskRunnerThread producer_thread("perfetto.prd");
148 producer_thread.Start(std::unique_ptr<FakeProducerDelegate>(
149 new FakeProducerDelegate(data, size, posted_on_produced_and_committed)));
150
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100151 helper.ConnectConsumer();
152
Florian Mayer60d1e132018-01-26 15:00:52 +0000153 TraceConfig trace_config;
Florian Mayer4c3580f2018-02-12 15:59:55 +0000154 trace_config.add_buffers()->set_size_kb(8);
Florian Mayer60d1e132018-01-26 15:00:52 +0000155
Florian Mayer60d1e132018-01-26 15:00:52 +0000156 auto* ds_config = trace_config.add_data_sources()->mutable_config();
157 ds_config->set_name("android.perfetto.FakeProducer");
158 ds_config->set_target_buffer(0);
159
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100160 auto producer_enabled = task_runner.CreateCheckpoint("producer.enabled");
161 task_runner.PostTask(producer_enabled);
162 helper.StartTracing(trace_config);
Lalit Magantidd95ef92018-03-23 09:42:48 +0000163 task_runner.RunUntilCheckpoint("produced.and.committed");
Lalit Magantibfc3d3e2018-03-22 20:28:38 +0000164
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100165 auto on_readback_complete = task_runner.CreateCheckpoint("readback.complete");
166 auto on_consumer_data =
Primiano Tucci07e104d2018-04-03 20:45:35 +0200167 [&on_readback_complete](const protos::TracePacket& packet) {
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100168 if (packet.for_testing().str() == "end")
169 on_readback_complete();
170 };
171 helper.ReadData(on_consumer_data, [] {});
Lalit Magantidd95ef92018-03-23 09:42:48 +0000172 task_runner.RunUntilCheckpoint("readback.complete");
173
Florian Mayer60d1e132018-01-26 15:00:52 +0000174 return 0;
175}
176
177} // namespace shm_fuzz
178} // namespace perfetto
179
180extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
181
182extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
183 return perfetto::shm_fuzz::FuzzSharedMemory(data, size);
184}