blob: 8f32b5ffc7903491b1d40961d682ccd602cd27a6 [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"
Florian Mayer60d1e132018-01-26 15:00:52 +000026#include "perfetto/trace/trace_packet.pb.h"
27#include "perfetto/trace/trace_packet.pbzero.h"
28#include "perfetto/tracing/core/data_source_config.h"
29#include "perfetto/tracing/core/data_source_descriptor.h"
30#include "perfetto/tracing/core/producer.h"
31#include "perfetto/tracing/core/trace_writer.h"
32#include "perfetto/tracing/ipc/producer_ipc_client.h"
33#include "perfetto/tracing/ipc/service_ipc_host.h"
34#include "src/base/test/test_task_runner.h"
35#include "test/fake_consumer.h"
36#include "test/task_runner_thread.h"
Lalit Magantibfc3d3e2018-03-22 20:28:38 +000037#include "test/task_runner_thread_delegates.h"
Florian Mayer60d1e132018-01-26 15:00:52 +000038
Florian Mayer60d1e132018-01-26 15:00:52 +000039namespace perfetto {
40namespace shm_fuzz {
41
Florian Mayer43374ba2018-02-16 13:35:16 +000042static const char* kProducerSocket = tempnam("/tmp", "perfetto-producer");
43static const char* kConsumerSocket = tempnam("/tmp", "perfetto-consumer");
44
Florian Mayer60d1e132018-01-26 15:00:52 +000045// Fake producer writing a protozero message of data into shared memory
46// buffer, followed by a sentinel message to signal completion to the
47// consumer.
48class FakeProducer : public Producer {
49 public:
Florian Mayer20c2c722018-02-15 14:10:16 +000050 FakeProducer(std::string name,
51 const uint8_t* data,
52 size_t size,
53 FakeConsumer* consumer)
54 : name_(std::move(name)), data_(data), size_(size), consumer_(consumer) {}
Florian Mayer60d1e132018-01-26 15:00:52 +000055
56 void Connect(const char* socket_name, base::TaskRunner* task_runner) {
57 endpoint_ = ProducerIPCClient::Connect(socket_name, this, task_runner);
58 }
59
60 void OnConnect() override {
61 DataSourceDescriptor descriptor;
62 descriptor.set_name(name_);
63 endpoint_->RegisterDataSource(descriptor,
64 [this](DataSourceID id) { id_ = id; });
65 }
66
67 void OnDisconnect() override {}
68
69 void CreateDataSourceInstance(
70 DataSourceInstanceID,
71 const DataSourceConfig& source_config) override {
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000072 // The block is to destroy |packet| and |trace_writer| in order. Destroying
73 // the |trace_writer| will cause a flush of the completed packets.
74 {
75 auto trace_writer = endpoint_->CreateTraceWriter(
76 static_cast<BufferID>(source_config.target_buffer()));
77 auto packet = trace_writer->NewTracePacket();
78 packet->stream_writer_->WriteBytes(data_, size_);
79 packet->Finalize();
80 }
81 {
82 auto trace_writer = endpoint_->CreateTraceWriter(
83 static_cast<BufferID>(source_config.target_buffer()));
84 auto end_packet = trace_writer->NewTracePacket();
85 end_packet->set_for_testing()->set_str("end");
86 end_packet->Finalize();
87 }
Florian Mayer20c2c722018-02-15 14:10:16 +000088 consumer_->BusyWaitReadBuffers();
Florian Mayer60d1e132018-01-26 15:00:52 +000089 }
90
91 void TearDownDataSourceInstance(DataSourceInstanceID) override {}
Isabelle Taylor69faa902018-03-21 15:42:03 +000092 void OnTracingStart() override {}
93 void OnTracingStop() override {}
Florian Mayer60d1e132018-01-26 15:00:52 +000094
95 private:
96 const std::string name_;
97 const uint8_t* data_;
98 const size_t size_;
99 DataSourceID id_ = 0;
100 std::unique_ptr<Service::ProducerEndpoint> endpoint_;
Florian Mayer20c2c722018-02-15 14:10:16 +0000101 FakeConsumer* consumer_;
Florian Mayer60d1e132018-01-26 15:00:52 +0000102};
103
104class FakeProducerDelegate : public ThreadDelegate {
105 public:
Florian Mayer20c2c722018-02-15 14:10:16 +0000106 FakeProducerDelegate(const uint8_t* data, size_t size, FakeConsumer* consumer)
107 : data_(data), size_(size), consumer_(consumer) {}
Florian Mayer60d1e132018-01-26 15:00:52 +0000108 ~FakeProducerDelegate() override = default;
109
110 void Initialize(base::TaskRunner* task_runner) override {
Florian Mayer20c2c722018-02-15 14:10:16 +0000111 producer_.reset(new FakeProducer("android.perfetto.FakeProducer", data_,
112 size_, consumer_));
Florian Mayer43374ba2018-02-16 13:35:16 +0000113 producer_->Connect(kProducerSocket, task_runner);
Florian Mayer60d1e132018-01-26 15:00:52 +0000114 }
115
116 private:
117 std::unique_ptr<FakeProducer> producer_;
118 const uint8_t* data_;
119 const size_t size_;
Florian Mayer20c2c722018-02-15 14:10:16 +0000120 FakeConsumer* consumer_;
Florian Mayer60d1e132018-01-26 15:00:52 +0000121};
122
Florian Mayer60d1e132018-01-26 15:00:52 +0000123int FuzzSharedMemory(const uint8_t* data, size_t size);
124
125int FuzzSharedMemory(const uint8_t* data, size_t size) {
Lalit Magantibfc3d3e2018-03-22 20:28:38 +0000126 TaskRunnerThread service_thread("perfetto.svc");
127 service_thread.Start(std::unique_ptr<ServiceDelegate>(
128 new ServiceDelegate(kProducerSocket, kConsumerSocket)));
Florian Mayer60d1e132018-01-26 15:00:52 +0000129
Florian Mayer60d1e132018-01-26 15:00:52 +0000130 // Setup the TraceConfig for the consumer.
131 TraceConfig trace_config;
Florian Mayer4c3580f2018-02-12 15:59:55 +0000132 trace_config.add_buffers()->set_size_kb(8);
Florian Mayer20c2c722018-02-15 14:10:16 +0000133 trace_config.set_duration_ms(1000);
Florian Mayer60d1e132018-01-26 15:00:52 +0000134
135 // Create the buffer for ftrace.
136 auto* ds_config = trace_config.add_data_sources()->mutable_config();
137 ds_config->set_name("android.perfetto.FakeProducer");
138 ds_config->set_target_buffer(0);
139
140 base::TestTaskRunner task_runner;
141 auto finish = task_runner.CreateCheckpoint("no.more.packets");
142 // Wait for sentinel message from Producer, then signal no.more.packets.
143 auto function = [&finish](std::vector<TracePacket> packets, bool has_more) {
144 for (auto& p : packets) {
145 p.Decode();
Hector Dearmanfaa22f82018-02-14 12:02:51 +0000146 if (p->for_testing().str() == "end")
Florian Mayer60d1e132018-01-26 15:00:52 +0000147 finish();
148 }
149 };
Lalit Magantibfc3d3e2018-03-22 20:28:38 +0000150 auto on_connect = task_runner.CreateCheckpoint("consumer.connected");
151 FakeConsumer consumer(trace_config, std::move(on_connect),
152 std::move(function), &task_runner);
Florian Mayer43374ba2018-02-16 13:35:16 +0000153 consumer.Connect(kConsumerSocket);
Lalit Magantibfc3d3e2018-03-22 20:28:38 +0000154 task_runner.RunUntilCheckpoint("consumer.connected");
Florian Mayer20c2c722018-02-15 14:10:16 +0000155
Lalit Magantibfc3d3e2018-03-22 20:28:38 +0000156 consumer.EnableTracing();
157
158 TaskRunnerThread producer_thread("perfetto.prd");
Florian Mayer20c2c722018-02-15 14:10:16 +0000159 producer_thread.Start(std::unique_ptr<FakeProducerDelegate>(
160 new FakeProducerDelegate(data, size, &consumer)));
Florian Mayer60d1e132018-01-26 15:00:52 +0000161 task_runner.RunUntilCheckpoint("no.more.packets");
162 return 0;
163}
164
165} // namespace shm_fuzz
166} // namespace perfetto
167
168extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
169
170extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
171 return perfetto::shm_fuzz::FuzzSharedMemory(data, size);
172}