• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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