1 // Copyright 2016 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 #include <string>
16
17 #include "absl/status/statusor.h"
18 #include "absl/types/optional.h"
19
20 #include <grpc/grpc.h>
21 #include <grpc/impl/channel_arg_names.h>
22 #include <grpc/slice.h>
23 #include <grpc/support/log.h>
24
25 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
26 #include "src/core/lib/channel/channel_args.h"
27 #include "src/core/lib/channel/channel_args_preconditioning.h"
28 #include "src/core/lib/config/core_configuration.h"
29 #include "src/core/lib/experiments/config.h"
30 #include "src/core/lib/gprpp/env.h"
31 #include "src/core/lib/gprpp/ref_counted_ptr.h"
32 #include "src/core/lib/iomgr/endpoint.h"
33 #include "src/core/lib/iomgr/exec_ctx.h"
34 #include "src/core/lib/surface/channel.h"
35 #include "src/core/lib/surface/channel_create.h"
36 #include "src/core/lib/surface/channel_stack_type.h"
37 #include "src/core/lib/transport/transport.h"
38 #include "src/libfuzzer/libfuzzer_macro.h"
39 #include "test/core/end2end/fuzzers/api_fuzzer.pb.h"
40 #include "test/core/end2end/fuzzers/fuzzer_input.pb.h"
41 #include "test/core/end2end/fuzzers/fuzzing_common.h"
42 #include "test/core/end2end/fuzzers/network_input.h"
43 #include "test/core/util/fuzz_config_vars.h"
44 #include "test/core/util/mock_endpoint.h"
45
46 bool squelch = true;
47 bool leak_check = true;
48
discard_write(grpc_slice)49 static void discard_write(grpc_slice /*slice*/) {}
50
dont_log(gpr_log_func_args *)51 static void dont_log(gpr_log_func_args* /*args*/) {}
52
53 namespace grpc_core {
54 namespace testing {
55
56 class ClientFuzzer final : public BasicFuzzer {
57 public:
ClientFuzzer(const fuzzer_input::Msg & msg)58 explicit ClientFuzzer(const fuzzer_input::Msg& msg)
59 : BasicFuzzer(msg.event_engine_actions()) {
60 ExecCtx exec_ctx;
61 UpdateMinimumRunTime(
62 ScheduleReads(msg.network_input()[0], mock_endpoint_, engine()));
63 ChannelArgs args =
64 CoreConfiguration::Get()
65 .channel_args_preconditioning()
66 .PreconditionChannelArgs(nullptr)
67 .SetIfUnset(GRPC_ARG_DEFAULT_AUTHORITY, "test-authority");
68 Transport* transport =
69 grpc_create_chttp2_transport(args, mock_endpoint_, true);
70 channel_ = ChannelCreate("test-target", args, GRPC_CLIENT_DIRECT_CHANNEL,
71 transport)
72 ->release()
73 ->c_ptr();
74 }
75
~ClientFuzzer()76 ~ClientFuzzer() { GPR_ASSERT(channel_ == nullptr); }
77
78 private:
CreateChannel(const api_fuzzer::CreateChannel &)79 Result CreateChannel(const api_fuzzer::CreateChannel&) override {
80 return Result::kFailed;
81 }
CreateServer(const api_fuzzer::CreateServer &)82 Result CreateServer(const api_fuzzer::CreateServer&) override {
83 return Result::kFailed;
84 }
DestroyServer()85 void DestroyServer() override {}
DestroyChannel()86 void DestroyChannel() override {
87 grpc_channel_destroy(channel_);
88 channel_ = nullptr;
89 }
90
server()91 grpc_server* server() override { return nullptr; }
channel()92 grpc_channel* channel() override { return channel_; }
93
94 grpc_endpoint* mock_endpoint_ = grpc_mock_endpoint_create(discard_write);
95 grpc_channel* channel_ = nullptr;
96 };
97
98 } // namespace testing
99 } // namespace grpc_core
100
DEFINE_PROTO_FUZZER(const fuzzer_input::Msg & msg)101 DEFINE_PROTO_FUZZER(const fuzzer_input::Msg& msg) {
102 if (squelch && !grpc_core::GetEnv("GRPC_TRACE_FUZZER").has_value()) {
103 gpr_set_log_function(dont_log);
104 }
105 if (msg.network_input().size() != 1) return;
106 grpc_core::ApplyFuzzConfigVars(msg.config_vars());
107 grpc_core::TestOnlyReloadExperimentsFromConfigVariables();
108 grpc_core::testing::ClientFuzzer(msg).Run(msg.api_actions());
109 }
110