17 #include "absl/memory/memory.h"
31 #include "src/libfuzzer/libfuzzer_macro.h"
32 #include "test/core/filters/filter_fuzzer.pb.h"
58 Arena*) ->
int { abort(); },
80 class FakeChannelSecurityConnector final
83 FakeChannelSecurityConnector()
98 return [
this, qry]() -> Poll<absl::Status> {
106 HandshakeManager*)
override {
121 class ConstAuthorizationEngine final :
public AuthorizationEngine {
123 explicit ConstAuthorizationEngine(AuthorizationEngine::Decision decision)
126 Decision Evaluate(
const EvaluateArgs&)
const override {
return decision_; }
132 class FakeAuthorizationPolicyProvider final
135 explicit FakeAuthorizationPolicyProvider(AuthorizationEngines engines)
137 void Orphan()
override {}
138 AuthorizationEngines engines()
override {
return engines_; }
144 struct GlobalObjects {
148 MakeRefCounted<FakeChannelSecurityConnector>()};
150 void Perform(
const filter_fuzzer::GlobalObjectAction&
action) {
151 switch (
action.type_case()) {
152 case filter_fuzzer::GlobalObjectAction::TYPE_NOT_SET:
154 case filter_fuzzer::GlobalObjectAction::kSetResourceQuota:
157 case filter_fuzzer::GlobalObjectAction::kFinishCheckCallHost:
159 action.finish_check_call_host().qry(),
162 action.finish_check_call_host().message()));
168 RefCountedPtr<AuthorizationEngine> LoadAuthorizationEngine(
169 const filter_fuzzer::AuthorizationEngine& engine) {
170 switch (engine.engine_case()) {
171 case filter_fuzzer::AuthorizationEngine::kAlwaysAllow:
172 return MakeRefCounted<ConstAuthorizationEngine>(
173 AuthorizationEngine::Decision{
175 engine.always_allow()});
176 case filter_fuzzer::AuthorizationEngine::kAlwaysDeny:
177 return MakeRefCounted<ConstAuthorizationEngine>(
178 AuthorizationEngine::Decision{
180 engine.always_deny()});
181 case filter_fuzzer::AuthorizationEngine::ENGINE_NOT_SET:
184 return MakeRefCounted<ConstAuthorizationEngine>(AuthorizationEngine::Decision{
188 template <
typename FuzzerChannelArgs>
189 ChannelArgs LoadChannelArgs(
const FuzzerChannelArgs& fuzz_args,
190 GlobalObjects* globals) {
192 for (
const auto&
arg : fuzz_args) {
194 if (
arg.value_case() == filter_fuzzer::ChannelArg::kResourceQuota) {
195 args =
args.SetObject(globals->resource_quota);
198 if (
arg.value_case() == filter_fuzzer::ChannelArg::kTransport) {
199 args =
args.SetObject(&globals->transport);
202 if (
arg.value_case() ==
203 filter_fuzzer::ChannelArg::kChannelSecurityConnector) {
204 args =
args.SetObject(globals->channel_security_connector);
207 if (
arg.value_case() == filter_fuzzer::ChannelArg::kAuthContext) {
208 args =
args.SetObject(MakeRefCounted<grpc_auth_context>(
nullptr));
211 if (
arg.value_case() ==
212 filter_fuzzer::ChannelArg::kAuthorizationPolicyProvider) {
213 args =
args.SetObject(MakeRefCounted<FakeAuthorizationPolicyProvider>(
215 LoadAuthorizationEngine(
216 arg.authorization_policy_provider().allow_engine()),
217 LoadAuthorizationEngine(
218 arg.authorization_policy_provider().deny_engine())}));
221 switch (
arg.value_case()) {
222 case filter_fuzzer::ChannelArg::VALUE_NOT_SET:
224 case filter_fuzzer::ChannelArg::kStr:
227 case filter_fuzzer::ChannelArg::kI:
230 case filter_fuzzer::ChannelArg::kResourceQuota:
231 case filter_fuzzer::ChannelArg::kTransport:
232 case filter_fuzzer::ChannelArg::kChannelSecurityConnector:
233 case filter_fuzzer::ChannelArg::kAuthContext:
234 case filter_fuzzer::ChannelArg::kAuthorizationPolicyProvider:
254 if (
name == kFilters[i]->
name)
return kFilters[
i];
261 MainLoop(RefCountedPtr<grpc_channel_stack> channel_stack,
262 ChannelArgs channel_args)
265 ->CreateMemoryAllocator(
"test")),
274 void Run(
const filter_fuzzer::Action&
action, GlobalObjects* globals) {
277 if (
auto*
call = GetCall(
id))
call->Wakeup();
279 switch (
action.type_case()) {
280 case filter_fuzzer::Action::TYPE_NOT_SET:
282 case filter_fuzzer::Action::kAdvanceTimeMicroseconds:
287 case filter_fuzzer::Action::kCancel:
290 case filter_fuzzer::Action::kCreateCall:
293 absl::make_unique<Call>(
this,
action.call(),
action.create_call()));
295 case filter_fuzzer::Action::kReceiveInitialMetadata:
297 call->RecvInitialMetadata(
action.receive_initial_metadata());
300 case filter_fuzzer::Action::kReceiveTrailingMetadata:
302 call->RecvTrailingMetadata(
action.receive_trailing_metadata());
305 case filter_fuzzer::Action::kSetFinalInfo:
310 case filter_fuzzer::Action::kGlobalObjectAction:
311 globals->Perform(
action.global_object_action());
317 MakePromiseBasedFilter<Call::EndFilter, FilterEndpoint::kClient>(
320 MakePromiseBasedFilter<Call::EndFilter, FilterEndpoint::kServer>(
322 return is_client ? &client_filter : &server_filter;
332 return is_client ? &client_filter : &server_filter;
336 class WakeCall final :
public Wakeable {
338 WakeCall(MainLoop* main_loop,
uint32_t id)
340 void Wakeup()
override {
342 if (already ==
id_)
return;
347 void Drop()
override {
delete this; }
354 class Call final :
public Activity {
357 class EndFilter :
public ChannelFilter {
365 ArenaPromise<ServerMetadataHandle> MakeCallPromise(
368 if (
call->server_initial_metadata_) {
369 call_args.server_initial_metadata->Set(
370 call->server_initial_metadata_.get());
372 call->unset_incoming_server_initial_metadata_latch_ =
373 call_args.server_initial_metadata;
375 return [
call]() -> Poll<ServerMetadataHandle> {
376 return call->CheckCompletion();
382 class BottomFilter :
public ChannelFilter {
386 return BottomFilter{};
390 ArenaPromise<ServerMetadataHandle> MakeCallPromise(
407 auto* server_initial_metadata =
arena_->New<Latch<ServerMetadata*>>();
409 CallArgs{
std::move(*LoadMetadata(client_initial_metadata,
411 server_initial_metadata});
420 std::unique_ptr<grpc_call_final_info> final_info;
422 final_info = absl::make_unique<grpc_call_final_info>();
423 final_info->final_status =
425 final_info->error_string =
final_info_->error_string().c_str();
426 final_info->stats.latency =
428 auto transport_stream_stats_from_proto =
429 [](
const filter_fuzzer::TransportOneWayStats&
stats) {
431 s.framing_bytes =
stats.framing_bytes();
432 s.data_bytes =
stats.data_bytes();
433 s.header_bytes =
stats.header_bytes();
436 final_info->stats.transport_stream_stats.incoming =
437 transport_stream_stats_from_proto(
final_info_->incoming());
438 final_info->stats.transport_stream_stats.outgoing =
439 transport_stream_stats_from_proto(
final_info_->outgoing());
451 void Orphan()
override { abort(); }
452 void ForceImmediateRepoll()
override {
context_->set_continue(); }
453 Waker MakeOwningWaker()
override {
456 Waker MakeNonOwningWaker()
override {
return MakeOwningWaker(); }
481 void SetFinalInfo(filter_fuzzer::FinalInfo final_info) {
482 final_info_ = absl::make_unique<filter_fuzzer::FinalInfo>(final_info);
487 :
public ScopedActivity,
488 public promise_detail::Context<Arena>,
489 public promise_detail::Context<grpc_call_context_element>,
490 public promise_detail::Context<CallFinalization> {
493 : ScopedActivity(
call),
500 call_->context_ =
this;
507 call_->context_ =
nullptr;
510 void set_continue() {
continue_ =
true; }
517 template <
typename R>
520 if (*
out !=
nullptr)
return absl::nullopt;
521 *
out = absl::make_unique<R>(
arena_.get());
531 auto r = (*promise_)();
532 if (absl::holds_alternative<Pending>(
r))
return;
538 Poll<ServerMetadataHandle> CheckCompletion() {
565 if (
it ==
calls_.end())
return nullptr;
566 return it->second.get();
571 std::map<uint32_t, std::unique_ptr<Call>>
calls_;
580 if (filter ==
nullptr)
return;
581 if (
msg.channel_stack_type() < 0 ||
587 char* grpc_trace_fuzzer =
gpr_getenv(
"GRPC_TRACE_FUZZER");
600 grpc_core::GlobalObjects globals;
601 auto channel_args = grpc_core::LoadChannelArgs(
msg.channel_args(), &globals);
604 msg.stack_name().c_str(),
606 builder.SetChannelArgs(channel_args);
608 const bool is_client =
611 builder.AppendFilter(grpc_core::MainLoop::EndFilter(
true));
613 builder.PrependFilter(grpc_core::MainLoop::EndFilter(
false));
615 builder.AppendFilter(grpc_core::MainLoop::BottomFilter(is_client));
623 for (
const auto&
action :
msg.actions()) {
625 main_loop.Run(
action, &globals);