blob: bb6d90e0f26a12904617c051ac8036ce96374706 [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"
Primiano Tucci2c5488f2019-06-01 03:27:28 +010023#include "perfetto/ext/base/utils.h"
24#include "perfetto/ext/tracing/core/data_source_config.h"
25#include "perfetto/ext/tracing/core/data_source_descriptor.h"
26#include "perfetto/ext/tracing/core/producer.h"
27#include "perfetto/ext/tracing/core/trace_writer.h"
28#include "perfetto/ext/tracing/ipc/producer_ipc_client.h"
29#include "perfetto/ext/tracing/ipc/service_ipc_host.h"
Hector Dearmanfaa22f82018-02-14 12:02:51 +000030#include "perfetto/trace/test_event.pbzero.h"
Florian Mayer60d1e132018-01-26 15:00:52 +000031#include "src/base/test/test_task_runner.h"
Florian Mayerc29e0d32018-04-04 15:55:46 +010032#include "src/tracing/ipc/default_socket.h"
Florian Mayer60d1e132018-01-26 15:00:52 +000033#include "test/task_runner_thread.h"
Lalit Magantibfc3d3e2018-03-22 20:28:38 +000034#include "test/task_runner_thread_delegates.h"
Lalit Magantic4c3ceb2018-03-29 20:38:13 +010035#include "test/test_helper.h"
Florian Mayer60d1e132018-01-26 15:00:52 +000036
Primiano Tucci07e104d2018-04-03 20:45:35 +020037#include "perfetto/trace/trace_packet.pbzero.h"
38
Florian Mayer60d1e132018-01-26 15:00:52 +000039namespace perfetto {
40namespace shm_fuzz {
41
Lalit Magantic4c3ceb2018-03-29 20:38:13 +010042// If we're building on Android and starting the daemons ourselves,
43// create the sockets in a world-writable location.
44#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
45 PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
46#define TEST_PRODUCER_SOCK_NAME "/data/local/tmp/traced_producer"
47#else
Florian Mayerc29e0d32018-04-04 15:55:46 +010048#define TEST_PRODUCER_SOCK_NAME ::perfetto::GetProducerSocket()
Lalit Magantic4c3ceb2018-03-29 20:38:13 +010049#endif
Florian Mayer43374ba2018-02-16 13:35:16 +000050
Florian Mayer60d1e132018-01-26 15:00:52 +000051// Fake producer writing a protozero message of data into shared memory
52// buffer, followed by a sentinel message to signal completion to the
53// consumer.
54class FakeProducer : public Producer {
55 public:
Florian Mayer20c2c722018-02-15 14:10:16 +000056 FakeProducer(std::string name,
57 const uint8_t* data,
58 size_t size,
Lalit Magantidd95ef92018-03-23 09:42:48 +000059 std::function<void()> on_produced_and_committed)
60 : name_(std::move(name)),
61 data_(data),
62 size_(size),
63 on_produced_and_committed_(on_produced_and_committed) {}
Florian Mayer60d1e132018-01-26 15:00:52 +000064
65 void Connect(const char* socket_name, base::TaskRunner* task_runner) {
Lalit Maganti8f47a5b2018-03-28 20:50:28 +010066 endpoint_ = ProducerIPCClient::Connect(
67 socket_name, this, "android.perfetto.FakeProducer", task_runner);
Florian Mayer60d1e132018-01-26 15:00:52 +000068 }
69
70 void OnConnect() override {
71 DataSourceDescriptor descriptor;
72 descriptor.set_name(name_);
Lalit Maganti79a69912018-03-29 17:32:29 +010073 endpoint_->RegisterDataSource(descriptor);
Florian Mayer60d1e132018-01-26 15:00:52 +000074 }
75
76 void OnDisconnect() override {}
77
Florian Mayerd0201d02018-10-02 15:14:36 +010078 void SetupDataSource(DataSourceInstanceID, const DataSourceConfig&) override {
79 }
Primiano Tucci674076d2018-10-01 10:41:09 +010080
Primiano Tucciafb72b52018-09-25 09:37:24 +010081 void StartDataSource(DataSourceInstanceID,
82 const DataSourceConfig& source_config) override {
Lalit Magantidd95ef92018-03-23 09:42:48 +000083 auto trace_writer = endpoint_->CreateTraceWriter(
84 static_cast<BufferID>(source_config.target_buffer()));
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000085 {
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000086 auto packet = trace_writer->NewTracePacket();
87 packet->stream_writer_->WriteBytes(data_, size_);
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000088 }
Lalit Magantidd95ef92018-03-23 09:42:48 +000089 trace_writer->Flush();
90
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000091 {
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000092 auto end_packet = trace_writer->NewTracePacket();
93 end_packet->set_for_testing()->set_str("end");
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000094 }
Lalit Magantidd95ef92018-03-23 09:42:48 +000095 trace_writer->Flush(on_produced_and_committed_);
Florian Mayer60d1e132018-01-26 15:00:52 +000096 }
97
Primiano Tucciafb72b52018-09-25 09:37:24 +010098 void StopDataSource(DataSourceInstanceID) override {}
Primiano Tuccidca727d2018-04-04 11:31:55 +020099 void OnTracingSetup() override {}
Primiano Tuccid52e6272018-04-06 19:06:53 +0200100 void Flush(FlushRequestID, const DataSourceInstanceID*, size_t) override {}
Ryan Savitskiba8a5f52019-05-14 11:58:21 +0100101 void ClearIncrementalState(const DataSourceInstanceID*, size_t) {}
Florian Mayer60d1e132018-01-26 15:00:52 +0000102
103 private:
104 const std::string name_;
105 const uint8_t* data_;
106 const size_t size_;
Florian Mayer6a1a4d52018-06-08 16:47:07 +0100107 std::unique_ptr<TracingService::ProducerEndpoint> endpoint_;
Lalit Magantidd95ef92018-03-23 09:42:48 +0000108 std::function<void()> on_produced_and_committed_;
Florian Mayer60d1e132018-01-26 15:00:52 +0000109};
110
111class FakeProducerDelegate : public ThreadDelegate {
112 public:
Lalit Magantidd95ef92018-03-23 09:42:48 +0000113 FakeProducerDelegate(const uint8_t* data,
114 size_t size,
115 std::function<void()> on_produced_and_committed)
116 : data_(data),
117 size_(size),
118 on_produced_and_committed_(on_produced_and_committed) {}
Florian Mayer60d1e132018-01-26 15:00:52 +0000119 ~FakeProducerDelegate() override = default;
120
121 void Initialize(base::TaskRunner* task_runner) override {
Florian Mayer20c2c722018-02-15 14:10:16 +0000122 producer_.reset(new FakeProducer("android.perfetto.FakeProducer", data_,
Lalit Magantidd95ef92018-03-23 09:42:48 +0000123 size_, on_produced_and_committed_));
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100124 producer_->Connect(TEST_PRODUCER_SOCK_NAME, task_runner);
Florian Mayer60d1e132018-01-26 15:00:52 +0000125 }
126
127 private:
128 std::unique_ptr<FakeProducer> producer_;
129 const uint8_t* data_;
130 const size_t size_;
Lalit Magantidd95ef92018-03-23 09:42:48 +0000131 std::function<void()> on_produced_and_committed_;
Florian Mayer60d1e132018-01-26 15:00:52 +0000132};
133
Florian Mayer60d1e132018-01-26 15:00:52 +0000134int FuzzSharedMemory(const uint8_t* data, size_t size);
135
136int FuzzSharedMemory(const uint8_t* data, size_t size) {
Lalit Magantidd95ef92018-03-23 09:42:48 +0000137 base::TestTaskRunner task_runner;
138
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100139 TestHelper helper(&task_runner);
140 helper.StartServiceIfRequired();
Florian Mayer60d1e132018-01-26 15:00:52 +0000141
Lalit Magantidd95ef92018-03-23 09:42:48 +0000142 TaskRunnerThread producer_thread("perfetto.prd");
143 producer_thread.Start(std::unique_ptr<FakeProducerDelegate>(
Lalit Maganti36557d82018-04-11 14:36:17 +0100144 new FakeProducerDelegate(data, size,
145 helper.WrapTask(task_runner.CreateCheckpoint(
146 "produced.and.committed")))));
Lalit Magantidd95ef92018-03-23 09:42:48 +0000147
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100148 helper.ConnectConsumer();
Lalit Maganti36557d82018-04-11 14:36:17 +0100149 helper.WaitForConsumerConnect();
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100150
Florian Mayer60d1e132018-01-26 15:00:52 +0000151 TraceConfig trace_config;
Florian Mayer4c3580f2018-02-12 15:59:55 +0000152 trace_config.add_buffers()->set_size_kb(8);
Florian Mayer60d1e132018-01-26 15:00:52 +0000153
Florian Mayer60d1e132018-01-26 15:00:52 +0000154 auto* ds_config = trace_config.add_data_sources()->mutable_config();
155 ds_config->set_name("android.perfetto.FakeProducer");
156 ds_config->set_target_buffer(0);
157
Lalit Magantic4c3ceb2018-03-29 20:38:13 +0100158 helper.StartTracing(trace_config);
Lalit Magantidd95ef92018-03-23 09:42:48 +0000159 task_runner.RunUntilCheckpoint("produced.and.committed");
Lalit Magantibfc3d3e2018-03-22 20:28:38 +0000160
Lalit Maganti36557d82018-04-11 14:36:17 +0100161 helper.ReadData();
162 helper.WaitForReadData();
Lalit Magantidd95ef92018-03-23 09:42:48 +0000163
Florian Mayer60d1e132018-01-26 15:00:52 +0000164 return 0;
165}
166
167} // namespace shm_fuzz
168} // namespace perfetto
169
170extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
171
172extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
173 return perfetto::shm_fuzz::FuzzSharedMemory(data, size);
174}