• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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/trace/test_event.pbzero.h"
25 #include "perfetto/tracing/core/data_source_config.h"
26 #include "perfetto/tracing/core/data_source_descriptor.h"
27 #include "perfetto/tracing/core/producer.h"
28 #include "perfetto/tracing/core/trace_writer.h"
29 #include "perfetto/tracing/ipc/producer_ipc_client.h"
30 #include "perfetto/tracing/ipc/service_ipc_host.h"
31 #include "src/base/test/test_task_runner.h"
32 #include "src/tracing/ipc/default_socket.h"
33 #include "test/task_runner_thread.h"
34 #include "test/task_runner_thread_delegates.h"
35 #include "test/test_helper.h"
36 
37 #include "perfetto/trace/trace_packet.pb.h"
38 #include "perfetto/trace/trace_packet.pbzero.h"
39 
40 namespace perfetto {
41 namespace shm_fuzz {
42 
43 // If we're building on Android and starting the daemons ourselves,
44 // create the sockets in a world-writable location.
45 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
46     PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
47 #define TEST_PRODUCER_SOCK_NAME "/data/local/tmp/traced_producer"
48 #else
49 #define TEST_PRODUCER_SOCK_NAME ::perfetto::GetProducerSocket()
50 #endif
51 
52 // Fake producer writing a protozero message of data into shared memory
53 // buffer, followed by a sentinel message to signal completion to the
54 // consumer.
55 class FakeProducer : public Producer {
56  public:
FakeProducer(std::string name,const uint8_t * data,size_t size,std::function<void ()> on_produced_and_committed)57   FakeProducer(std::string name,
58                const uint8_t* data,
59                size_t size,
60                std::function<void()> on_produced_and_committed)
61       : name_(std::move(name)),
62         data_(data),
63         size_(size),
64         on_produced_and_committed_(on_produced_and_committed) {}
65 
Connect(const char * socket_name,base::TaskRunner * task_runner)66   void Connect(const char* socket_name, base::TaskRunner* task_runner) {
67     endpoint_ = ProducerIPCClient::Connect(
68         socket_name, this, "android.perfetto.FakeProducer", task_runner);
69   }
70 
OnConnect()71   void OnConnect() override {
72     DataSourceDescriptor descriptor;
73     descriptor.set_name(name_);
74     endpoint_->RegisterDataSource(descriptor);
75   }
76 
OnDisconnect()77   void OnDisconnect() override {}
78 
SetupDataSource(DataSourceInstanceID,const DataSourceConfig &)79   void SetupDataSource(DataSourceInstanceID, const DataSourceConfig&) override {
80   }
81 
StartDataSource(DataSourceInstanceID,const DataSourceConfig & source_config)82   void StartDataSource(DataSourceInstanceID,
83                        const DataSourceConfig& source_config) override {
84     auto trace_writer = endpoint_->CreateTraceWriter(
85         static_cast<BufferID>(source_config.target_buffer()));
86     {
87       auto packet = trace_writer->NewTracePacket();
88       packet->stream_writer_->WriteBytes(data_, size_);
89     }
90     trace_writer->Flush();
91 
92     {
93       auto end_packet = trace_writer->NewTracePacket();
94       end_packet->set_for_testing()->set_str("end");
95     }
96     trace_writer->Flush(on_produced_and_committed_);
97   }
98 
StopDataSource(DataSourceInstanceID)99   void StopDataSource(DataSourceInstanceID) override {}
OnTracingSetup()100   void OnTracingSetup() override {}
Flush(FlushRequestID,const DataSourceInstanceID *,size_t)101   void Flush(FlushRequestID, const DataSourceInstanceID*, size_t) override {}
ClearIncrementalState(const DataSourceInstanceID *,size_t)102   void ClearIncrementalState(const DataSourceInstanceID*, size_t) {}
103 
104  private:
105   const std::string name_;
106   const uint8_t* data_;
107   const size_t size_;
108   std::unique_ptr<TracingService::ProducerEndpoint> endpoint_;
109   std::function<void()> on_produced_and_committed_;
110 };
111 
112 class FakeProducerDelegate : public ThreadDelegate {
113  public:
FakeProducerDelegate(const uint8_t * data,size_t size,std::function<void ()> on_produced_and_committed)114   FakeProducerDelegate(const uint8_t* data,
115                        size_t size,
116                        std::function<void()> on_produced_and_committed)
117       : data_(data),
118         size_(size),
119         on_produced_and_committed_(on_produced_and_committed) {}
120   ~FakeProducerDelegate() override = default;
121 
Initialize(base::TaskRunner * task_runner)122   void Initialize(base::TaskRunner* task_runner) override {
123     producer_.reset(new FakeProducer("android.perfetto.FakeProducer", data_,
124                                      size_, on_produced_and_committed_));
125     producer_->Connect(TEST_PRODUCER_SOCK_NAME, task_runner);
126   }
127 
128  private:
129   std::unique_ptr<FakeProducer> producer_;
130   const uint8_t* data_;
131   const size_t size_;
132   std::function<void()> on_produced_and_committed_;
133 };
134 
135 int FuzzSharedMemory(const uint8_t* data, size_t size);
136 
FuzzSharedMemory(const uint8_t * data,size_t size)137 int FuzzSharedMemory(const uint8_t* data, size_t size) {
138   base::TestTaskRunner task_runner;
139 
140   TestHelper helper(&task_runner);
141   helper.StartServiceIfRequired();
142 
143   TaskRunnerThread producer_thread("perfetto.prd");
144   producer_thread.Start(std::unique_ptr<FakeProducerDelegate>(
145       new FakeProducerDelegate(data, size,
146                                helper.WrapTask(task_runner.CreateCheckpoint(
147                                    "produced.and.committed")))));
148 
149   helper.ConnectConsumer();
150   helper.WaitForConsumerConnect();
151 
152   TraceConfig trace_config;
153   trace_config.add_buffers()->set_size_kb(8);
154 
155   auto* ds_config = trace_config.add_data_sources()->mutable_config();
156   ds_config->set_name("android.perfetto.FakeProducer");
157   ds_config->set_target_buffer(0);
158 
159   helper.StartTracing(trace_config);
160   task_runner.RunUntilCheckpoint("produced.and.committed");
161 
162   helper.ReadData();
163   helper.WaitForReadData();
164 
165   return 0;
166 }
167 
168 }  // namespace shm_fuzz
169 }  // namespace perfetto
170 
171 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
172 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)173 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
174   return perfetto::shm_fuzz::FuzzSharedMemory(data, size);
175 }
176