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