blob: 454f3c0e0f49fd485e5c6bcb98fe71e657536c58 [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"
37
Florian Mayer60d1e132018-01-26 15:00:52 +000038namespace perfetto {
39namespace shm_fuzz {
40
Florian Mayer43374ba2018-02-16 13:35:16 +000041static const char* kProducerSocket = tempnam("/tmp", "perfetto-producer");
42static const char* kConsumerSocket = tempnam("/tmp", "perfetto-consumer");
43
Florian Mayer60d1e132018-01-26 15:00:52 +000044// Fake producer writing a protozero message of data into shared memory
45// buffer, followed by a sentinel message to signal completion to the
46// consumer.
47class FakeProducer : public Producer {
48 public:
Florian Mayer20c2c722018-02-15 14:10:16 +000049 FakeProducer(std::string name,
50 const uint8_t* data,
51 size_t size,
52 FakeConsumer* consumer)
53 : name_(std::move(name)), data_(data), size_(size), consumer_(consumer) {}
Florian Mayer60d1e132018-01-26 15:00:52 +000054
55 void Connect(const char* socket_name, base::TaskRunner* task_runner) {
56 endpoint_ = ProducerIPCClient::Connect(socket_name, this, task_runner);
57 }
58
59 void OnConnect() override {
60 DataSourceDescriptor descriptor;
61 descriptor.set_name(name_);
62 endpoint_->RegisterDataSource(descriptor,
63 [this](DataSourceID id) { id_ = id; });
64 }
65
66 void OnDisconnect() override {}
67
68 void CreateDataSourceInstance(
69 DataSourceInstanceID,
70 const DataSourceConfig& source_config) override {
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000071 // The block is to destroy |packet| and |trace_writer| in order. Destroying
72 // the |trace_writer| will cause a flush of the completed packets.
73 {
74 auto trace_writer = endpoint_->CreateTraceWriter(
75 static_cast<BufferID>(source_config.target_buffer()));
76 auto packet = trace_writer->NewTracePacket();
77 packet->stream_writer_->WriteBytes(data_, size_);
78 packet->Finalize();
79 }
80 {
81 auto trace_writer = endpoint_->CreateTraceWriter(
82 static_cast<BufferID>(source_config.target_buffer()));
83 auto end_packet = trace_writer->NewTracePacket();
84 end_packet->set_for_testing()->set_str("end");
85 end_packet->Finalize();
86 }
Florian Mayer20c2c722018-02-15 14:10:16 +000087 consumer_->BusyWaitReadBuffers();
Florian Mayer60d1e132018-01-26 15:00:52 +000088 }
89
90 void TearDownDataSourceInstance(DataSourceInstanceID) override {}
91
92 private:
93 const std::string name_;
94 const uint8_t* data_;
95 const size_t size_;
96 DataSourceID id_ = 0;
97 std::unique_ptr<Service::ProducerEndpoint> endpoint_;
Florian Mayer20c2c722018-02-15 14:10:16 +000098 FakeConsumer* consumer_;
Florian Mayer60d1e132018-01-26 15:00:52 +000099};
100
101class FakeProducerDelegate : public ThreadDelegate {
102 public:
Florian Mayer20c2c722018-02-15 14:10:16 +0000103 FakeProducerDelegate(const uint8_t* data, size_t size, FakeConsumer* consumer)
104 : data_(data), size_(size), consumer_(consumer) {}
Florian Mayer60d1e132018-01-26 15:00:52 +0000105 ~FakeProducerDelegate() override = default;
106
107 void Initialize(base::TaskRunner* task_runner) override {
Florian Mayer20c2c722018-02-15 14:10:16 +0000108 producer_.reset(new FakeProducer("android.perfetto.FakeProducer", data_,
109 size_, consumer_));
Florian Mayer43374ba2018-02-16 13:35:16 +0000110 producer_->Connect(kProducerSocket, task_runner);
Florian Mayer60d1e132018-01-26 15:00:52 +0000111 }
112
113 private:
114 std::unique_ptr<FakeProducer> producer_;
115 const uint8_t* data_;
116 const size_t size_;
Florian Mayer20c2c722018-02-15 14:10:16 +0000117 FakeConsumer* consumer_;
Florian Mayer60d1e132018-01-26 15:00:52 +0000118};
119
120class ServiceDelegate : public ThreadDelegate {
121 public:
122 ServiceDelegate() = default;
123 ~ServiceDelegate() override = default;
124 void Initialize(base::TaskRunner* task_runner) override {
125 svc_ = ServiceIPCHost::CreateInstance(task_runner);
Florian Mayer43374ba2018-02-16 13:35:16 +0000126 unlink(kProducerSocket);
127 unlink(kConsumerSocket);
128 svc_->Start(kProducerSocket, kConsumerSocket);
Florian Mayer60d1e132018-01-26 15:00:52 +0000129 }
130
131 private:
132 std::unique_ptr<ServiceIPCHost> svc_;
133 base::ScopedFile producer_fd_;
134 base::ScopedFile consumer_fd_;
135};
136
137int FuzzSharedMemory(const uint8_t* data, size_t size);
138
139int FuzzSharedMemory(const uint8_t* data, size_t size) {
140 TaskRunnerThread service_thread;
141 service_thread.Start(std::unique_ptr<ServiceDelegate>(new ServiceDelegate()));
142
Florian Mayer60d1e132018-01-26 15:00:52 +0000143 // Setup the TraceConfig for the consumer.
144 TraceConfig trace_config;
Florian Mayer4c3580f2018-02-12 15:59:55 +0000145 trace_config.add_buffers()->set_size_kb(8);
Florian Mayer20c2c722018-02-15 14:10:16 +0000146 trace_config.set_duration_ms(1000);
Florian Mayer60d1e132018-01-26 15:00:52 +0000147
148 // Create the buffer for ftrace.
149 auto* ds_config = trace_config.add_data_sources()->mutable_config();
150 ds_config->set_name("android.perfetto.FakeProducer");
151 ds_config->set_target_buffer(0);
152
153 base::TestTaskRunner task_runner;
154 auto finish = task_runner.CreateCheckpoint("no.more.packets");
155 // Wait for sentinel message from Producer, then signal no.more.packets.
156 auto function = [&finish](std::vector<TracePacket> packets, bool has_more) {
157 for (auto& p : packets) {
158 p.Decode();
Hector Dearmanfaa22f82018-02-14 12:02:51 +0000159 if (p->for_testing().str() == "end")
Florian Mayer60d1e132018-01-26 15:00:52 +0000160 finish();
161 }
162 };
163 FakeConsumer consumer(trace_config, std::move(function), &task_runner);
Florian Mayer43374ba2018-02-16 13:35:16 +0000164 consumer.Connect(kConsumerSocket);
Florian Mayer20c2c722018-02-15 14:10:16 +0000165
166 TaskRunnerThread producer_thread;
167 producer_thread.Start(std::unique_ptr<FakeProducerDelegate>(
168 new FakeProducerDelegate(data, size, &consumer)));
Florian Mayer60d1e132018-01-26 15:00:52 +0000169 task_runner.RunUntilCheckpoint("no.more.packets");
170 return 0;
171}
172
173} // namespace shm_fuzz
174} // namespace perfetto
175
176extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
177
178extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
179 return perfetto::shm_fuzz::FuzzSharedMemory(data, size);
180}