1 // Copyright 2021 gRPC authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef GRPC_TEST_CORE_TRANSPORT_BINDER_END2END_FUZZERS_FUZZER_UTILS_H 16 #define GRPC_TEST_CORE_TRANSPORT_BINDER_END2END_FUZZERS_FUZZER_UTILS_H 17 18 #include <memory> 19 #include <queue> 20 #include <string> 21 #include <thread> 22 #include <vector> 23 24 #include "absl/memory/memory.h" 25 #include "absl/status/status.h" 26 27 #include <grpc/support/log.h> 28 29 #include "src/core/ext/transport/binder/wire_format/binder.h" 30 #include "src/core/ext/transport/binder/wire_format/wire_reader.h" 31 #include "src/core/lib/gprpp/crash.h" 32 #include "test/core/transport/binder/end2end/fuzzers/binder_transport_fuzzer.pb.h" 33 34 namespace grpc_binder { 35 namespace fuzzing { 36 37 // A WritableParcel implementation that simply does nothing. Don't use 38 // MockWritableParcel here since capturing calls is expensive. 39 class NoOpWritableParcel : public WritableParcel { 40 public: GetDataSize()41 int32_t GetDataSize() const override { return 0; } WriteInt32(int32_t)42 absl::Status WriteInt32(int32_t /*data*/) override { 43 return absl::OkStatus(); 44 } WriteInt64(int64_t)45 absl::Status WriteInt64(int64_t /*data*/) override { 46 return absl::OkStatus(); 47 } WriteBinder(HasRawBinder *)48 absl::Status WriteBinder(HasRawBinder* /*binder*/) override { 49 return absl::OkStatus(); 50 } WriteString(absl::string_view)51 absl::Status WriteString(absl::string_view /*s*/) override { 52 return absl::OkStatus(); 53 } WriteByteArray(const int8_t *,int32_t)54 absl::Status WriteByteArray(const int8_t* /*buffer*/, 55 int32_t /*length*/) override { 56 return absl::OkStatus(); 57 } 58 }; 59 60 // Binder implementation used in fuzzing. 61 // 62 // Most of its the functionalities are no-op, except ConstructTxReceiver now 63 // returns a TransactionReceiverForFuzzing. 64 class BinderForFuzzing : public Binder { 65 public: BinderForFuzzing()66 BinderForFuzzing() : input_(std::make_unique<NoOpWritableParcel>()) {} 67 BinderForFuzzing(const binder_transport_fuzzer::IncomingParcels & p)68 explicit BinderForFuzzing(const binder_transport_fuzzer::IncomingParcels& p) 69 : incoming_parcels_(p), input_(std::make_unique<NoOpWritableParcel>()) {} 70 Initialize()71 void Initialize() override {} PrepareTransaction()72 absl::Status PrepareTransaction() override { return absl::OkStatus(); } 73 Transact(BinderTransportTxCode)74 absl::Status Transact(BinderTransportTxCode /*tx_code*/) override { 75 return absl::OkStatus(); 76 } 77 78 std::unique_ptr<TransactionReceiver> ConstructTxReceiver( 79 grpc_core::RefCountedPtr<WireReader> wire_reader_ref, 80 TransactionReceiver::OnTransactCb cb) const override; 81 GetWritableParcel()82 WritableParcel* GetWritableParcel() const override { return input_.get(); } GetRawBinder()83 void* GetRawBinder() override { return nullptr; } 84 85 private: 86 binder_transport_fuzzer::IncomingParcels incoming_parcels_; 87 std::unique_ptr<WritableParcel> input_; 88 }; 89 90 // ReadableParcel implementation used in fuzzing. 91 // 92 // It consumes a Parcel generated by mutator, and returns the data in the Parcel 93 // upon user's requests. 94 class ReadableParcelForFuzzing : public ReadableParcel { 95 public: ReadableParcelForFuzzing(const binder_transport_fuzzer::Parcel & p)96 explicit ReadableParcelForFuzzing(const binder_transport_fuzzer::Parcel& p) 97 : parcel_data_size_(p.data_size()), consumed_data_size_(0) { 98 for (const auto& v : p.values()) { 99 values_.push(v); 100 } 101 } 102 103 // Construct from SetupTransportParcel, which have fixed types of data in it. ReadableParcelForFuzzing(const binder_transport_fuzzer::SetupTransportParcel & p)104 explicit ReadableParcelForFuzzing( 105 const binder_transport_fuzzer::SetupTransportParcel& p) 106 : parcel_data_size_(p.data_size()), consumed_data_size_(0) { 107 // Creates value for protocol version and put it into the queue 108 binder_transport_fuzzer::Value version_value; 109 version_value.set_i32(p.version()); 110 values_.push(version_value); 111 112 // Creates a binder value and put it into the queue 113 binder_transport_fuzzer::Value binder_value; 114 binder_value.mutable_binder(); // sets one-of field 115 values_.push(binder_value); 116 } 117 118 int32_t GetDataSize() const override; 119 absl::Status ReadInt32(int32_t* data) override; 120 absl::Status ReadInt64(int64_t* data) override; 121 absl::Status ReadBinder(std::unique_ptr<Binder>* binder) override; 122 absl::Status ReadByteArray(std::string* data) override; 123 absl::Status ReadString(std::string* data) override; 124 125 private: 126 // Stores data/objects in binder in their order. Since we don't support random 127 // access using a std::queue is enough here. 128 std::queue<binder_transport_fuzzer::Value> values_; 129 130 const int32_t parcel_data_size_; 131 132 static constexpr size_t kParcelDataSizeLimit = 1024 * 1024; 133 size_t consumed_data_size_; 134 }; 135 136 void JoinFuzzingThread(); 137 138 // TransactionReceiver implementation used in fuzzing. 139 // 140 // When constructed, start sending fuzzed requests to the client. When all the 141 // bytes are consumed, the reference to WireReader will be released. 142 class TransactionReceiverForFuzzing : public TransactionReceiver { 143 public: 144 TransactionReceiverForFuzzing( 145 binder_transport_fuzzer::IncomingParcels incoming_parcels, 146 grpc_core::RefCountedPtr<WireReader> wire_reader_ref, 147 TransactionReceiver::OnTransactCb cb); 148 GetRawBinder()149 void* GetRawBinder() override { return nullptr; } 150 }; 151 152 } // namespace fuzzing 153 } // namespace grpc_binder 154 155 #endif // GRPC_TEST_CORE_TRANSPORT_BINDER_END2END_FUZZERS_FUZZER_UTILS_H 156