• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2016 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #include <string.h>
20 
21 #include <grpc/grpc.h>
22 #include <grpc/grpc_security.h>
23 #include <grpc/support/alloc.h>
24 #include <grpc/support/log.h>
25 #include <grpc/support/string_util.h>
26 
27 #include "src/core/ext/filters/client_channel/lb_policy_factory.h"
28 #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
29 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
30 #include "src/core/lib/channel/channel_args.h"
31 #include "src/core/lib/gpr/env.h"
32 #include "src/core/lib/iomgr/executor.h"
33 #include "src/core/lib/iomgr/resolve_address.h"
34 #include "src/core/lib/iomgr/tcp_client.h"
35 #include "src/core/lib/iomgr/timer.h"
36 #include "src/core/lib/iomgr/timer_manager.h"
37 #include "src/core/lib/slice/slice_internal.h"
38 #include "src/core/lib/surface/server.h"
39 #include "src/core/lib/transport/metadata.h"
40 #include "test/core/end2end/data/ssl_test_data.h"
41 #include "test/core/util/fuzzer_util.h"
42 #include "test/core/util/passthru_endpoint.h"
43 
44 using grpc_core::testing::grpc_fuzzer_get_next_byte;
45 using grpc_core::testing::grpc_fuzzer_get_next_string;
46 using grpc_core::testing::grpc_fuzzer_get_next_uint32;
47 using grpc_core::testing::input_stream;
48 
49 ////////////////////////////////////////////////////////////////////////////////
50 // logging
51 
52 bool squelch = true;
53 bool leak_check = true;
54 
dont_log(gpr_log_func_args * args)55 static void dont_log(gpr_log_func_args* args) {}
56 
57 ////////////////////////////////////////////////////////////////////////////////
58 // global state
59 
60 static gpr_timespec g_now;
61 static grpc_server* g_server;
62 static grpc_channel* g_channel;
63 static grpc_resource_quota* g_resource_quota;
64 
65 extern gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type);
66 
now_impl(gpr_clock_type clock_type)67 static gpr_timespec now_impl(gpr_clock_type clock_type) {
68   GPR_ASSERT(clock_type != GPR_TIMESPAN);
69   gpr_timespec ts = g_now;
70   ts.clock_type = clock_type;
71   return ts;
72 }
73 
end(input_stream * inp)74 static void end(input_stream* inp) { inp->cur = inp->end; }
75 
read_buffer(input_stream * inp,char ** buffer,size_t * length,bool * special)76 static void read_buffer(input_stream* inp, char** buffer, size_t* length,
77                         bool* special) {
78   *length = grpc_fuzzer_get_next_byte(inp);
79   if (*length == 255) {
80     if (special != nullptr) *special = true;
81     *length = grpc_fuzzer_get_next_byte(inp);
82   } else {
83     if (special != nullptr) *special = false;
84   }
85   *buffer = static_cast<char*>(gpr_malloc(*length));
86   for (size_t i = 0; i < *length; i++) {
87     (*buffer)[i] = static_cast<char>(grpc_fuzzer_get_next_byte(inp));
88   }
89 }
90 
maybe_intern(grpc_slice s,bool intern)91 static grpc_slice maybe_intern(grpc_slice s, bool intern) {
92   grpc_slice r = intern ? grpc_slice_intern(s) : grpc_slice_ref(s);
93   grpc_slice_unref(s);
94   return r;
95 }
96 
read_string_like_slice(input_stream * inp)97 static grpc_slice read_string_like_slice(input_stream* inp) {
98   bool special;
99   char* s = grpc_fuzzer_get_next_string(inp, &special);
100   grpc_slice r = maybe_intern(grpc_slice_from_copied_string(s), special);
101   gpr_free(s);
102   return r;
103 }
104 
read_buffer_like_slice(input_stream * inp)105 static grpc_slice read_buffer_like_slice(input_stream* inp) {
106   char* buffer;
107   size_t length;
108   bool special;
109   read_buffer(inp, &buffer, &length, &special);
110   grpc_slice r =
111       maybe_intern(grpc_slice_from_copied_buffer(buffer, length), special);
112   gpr_free(buffer);
113   return r;
114 }
115 
read_uint22(input_stream * inp)116 static uint32_t read_uint22(input_stream* inp) {
117   uint8_t b = grpc_fuzzer_get_next_byte(inp);
118   uint32_t x = b & 0x7f;
119   if (b & 0x80) {
120     x <<= 7;
121     b = grpc_fuzzer_get_next_byte(inp);
122     x |= b & 0x7f;
123     if (b & 0x80) {
124       x <<= 8;
125       x |= grpc_fuzzer_get_next_byte(inp);
126     }
127   }
128   return x;
129 }
130 
read_message(input_stream * inp)131 static grpc_byte_buffer* read_message(input_stream* inp) {
132   grpc_slice slice = grpc_slice_malloc(read_uint22(inp));
133   memset(GRPC_SLICE_START_PTR(slice), 0, GRPC_SLICE_LENGTH(slice));
134   grpc_byte_buffer* out = grpc_raw_byte_buffer_create(&slice, 1);
135   grpc_slice_unref(slice);
136   return out;
137 }
138 
read_int(input_stream * inp)139 static int read_int(input_stream* inp) {
140   return static_cast<int>(grpc_fuzzer_get_next_uint32(inp));
141 }
142 
read_args(input_stream * inp)143 static grpc_channel_args* read_args(input_stream* inp) {
144   size_t n = grpc_fuzzer_get_next_byte(inp);
145   grpc_arg* args = static_cast<grpc_arg*>(gpr_malloc(sizeof(*args) * n));
146   for (size_t i = 0; i < n; i++) {
147     switch (grpc_fuzzer_get_next_byte(inp)) {
148       case 1:
149         args[i].type = GRPC_ARG_STRING;
150         args[i].key = grpc_fuzzer_get_next_string(inp, nullptr);
151         args[i].value.string = grpc_fuzzer_get_next_string(inp, nullptr);
152         break;
153       case 2:
154         args[i].type = GRPC_ARG_INTEGER;
155         args[i].key = grpc_fuzzer_get_next_string(inp, nullptr);
156         args[i].value.integer = read_int(inp);
157         break;
158       case 3:
159         args[i].type = GRPC_ARG_POINTER;
160         args[i].key = gpr_strdup(GRPC_ARG_RESOURCE_QUOTA);
161         args[i].value.pointer.vtable = grpc_resource_quota_arg_vtable();
162         args[i].value.pointer.p = g_resource_quota;
163         grpc_resource_quota_ref(g_resource_quota);
164         break;
165       default:
166         end(inp);
167         n = i;
168         break;
169     }
170   }
171   grpc_channel_args* a =
172       static_cast<grpc_channel_args*>(gpr_malloc(sizeof(*a)));
173   a->args = args;
174   a->num_args = n;
175   return a;
176 }
177 
178 typedef struct cred_artifact_ctx {
179   int num_release;
180   char* release[3];
181 } cred_artifact_ctx;
182 #define CRED_ARTIFACT_CTX_INIT \
183   {                            \
184     0, { 0 }                   \
185   }
186 
cred_artifact_ctx_finish(cred_artifact_ctx * ctx)187 static void cred_artifact_ctx_finish(cred_artifact_ctx* ctx) {
188   for (int i = 0; i < ctx->num_release; i++) {
189     gpr_free(ctx->release[i]);
190   }
191 }
192 
read_cred_artifact(cred_artifact_ctx * ctx,input_stream * inp,const char ** builtins,size_t num_builtins)193 static const char* read_cred_artifact(cred_artifact_ctx* ctx, input_stream* inp,
194                                       const char** builtins,
195                                       size_t num_builtins) {
196   uint8_t b = grpc_fuzzer_get_next_byte(inp);
197   if (b == 0) return nullptr;
198   if (b == 1)
199     return ctx->release[ctx->num_release++] =
200                grpc_fuzzer_get_next_string(inp, nullptr);
201   if (b >= num_builtins + 1) {
202     end(inp);
203     return nullptr;
204   }
205   return builtins[b - 1];
206 }
207 
read_ssl_channel_creds(input_stream * inp)208 static grpc_channel_credentials* read_ssl_channel_creds(input_stream* inp) {
209   cred_artifact_ctx ctx = CRED_ARTIFACT_CTX_INIT;
210   static const char* builtin_root_certs[] = {test_root_cert};
211   static const char* builtin_private_keys[] = {
212       test_server1_key, test_self_signed_client_key, test_signed_client_key};
213   static const char* builtin_cert_chains[] = {
214       test_server1_cert, test_self_signed_client_cert, test_signed_client_cert};
215   const char* root_certs = read_cred_artifact(
216       &ctx, inp, builtin_root_certs, GPR_ARRAY_SIZE(builtin_root_certs));
217   const char* private_key = read_cred_artifact(
218       &ctx, inp, builtin_private_keys, GPR_ARRAY_SIZE(builtin_private_keys));
219   const char* certs = read_cred_artifact(&ctx, inp, builtin_cert_chains,
220                                          GPR_ARRAY_SIZE(builtin_cert_chains));
221   grpc_ssl_pem_key_cert_pair key_cert_pair = {private_key, certs};
222   grpc_channel_credentials* creds = grpc_ssl_credentials_create(
223       root_certs,
224       private_key != nullptr && certs != nullptr ? &key_cert_pair : nullptr,
225       nullptr, nullptr);
226   cred_artifact_ctx_finish(&ctx);
227   return creds;
228 }
229 
read_call_creds(input_stream * inp,int depth)230 static grpc_call_credentials* read_call_creds(input_stream* inp, int depth) {
231   if (depth > 64) {
232     // prevent creating infinitely deep call creds
233     end(inp);
234     return nullptr;
235   }
236   switch (grpc_fuzzer_get_next_byte(inp)) {
237     default:
238       end(inp);
239       return nullptr;
240     case 0:
241       return nullptr;
242     case 1: {
243       grpc_call_credentials* c1 = read_call_creds(inp, depth + 1);
244       grpc_call_credentials* c2 = read_call_creds(inp, depth + 1);
245       if (c1 != nullptr && c2 != nullptr) {
246         grpc_call_credentials* out =
247             grpc_composite_call_credentials_create(c1, c2, nullptr);
248         grpc_call_credentials_release(c1);
249         grpc_call_credentials_release(c2);
250         return out;
251       } else if (c1 != nullptr) {
252         return c1;
253       } else if (c2 != nullptr) {
254         return c2;
255       } else {
256         return nullptr;
257       }
258       GPR_UNREACHABLE_CODE(return nullptr);
259     }
260     case 2: {
261       cred_artifact_ctx ctx = CRED_ARTIFACT_CTX_INIT;
262       const char* access_token = read_cred_artifact(&ctx, inp, nullptr, 0);
263       grpc_call_credentials* out =
264           access_token == nullptr
265               ? nullptr
266               : grpc_access_token_credentials_create(access_token, nullptr);
267       cred_artifact_ctx_finish(&ctx);
268       return out;
269     }
270     case 3: {
271       cred_artifact_ctx ctx = CRED_ARTIFACT_CTX_INIT;
272       const char* auth_token = read_cred_artifact(&ctx, inp, nullptr, 0);
273       const char* auth_selector = read_cred_artifact(&ctx, inp, nullptr, 0);
274       grpc_call_credentials* out =
275           auth_token == nullptr || auth_selector == nullptr
276               ? nullptr
277               : grpc_google_iam_credentials_create(auth_token, auth_selector,
278                                                    nullptr);
279       cred_artifact_ctx_finish(&ctx);
280       return out;
281     }
282       /* TODO(ctiller): more cred types here */
283   }
284 }
285 
read_channel_creds(input_stream * inp)286 static grpc_channel_credentials* read_channel_creds(input_stream* inp) {
287   switch (grpc_fuzzer_get_next_byte(inp)) {
288     case 0:
289       return read_ssl_channel_creds(inp);
290       break;
291     case 1: {
292       grpc_channel_credentials* c1 = read_channel_creds(inp);
293       grpc_call_credentials* c2 = read_call_creds(inp, 0);
294       if (c1 != nullptr && c2 != nullptr) {
295         grpc_channel_credentials* out =
296             grpc_composite_channel_credentials_create(c1, c2, nullptr);
297         grpc_channel_credentials_release(c1);
298         grpc_call_credentials_release(c2);
299         return out;
300       } else if (c1) {
301         return c1;
302       } else if (c2) {
303         grpc_call_credentials_release(c2);
304         return nullptr;
305       } else {
306         return nullptr;
307       }
308       GPR_UNREACHABLE_CODE(return nullptr);
309     }
310     case 2:
311       return nullptr;
312     default:
313       end(inp);
314       return nullptr;
315   }
316 }
317 
is_eof(input_stream * inp)318 static bool is_eof(input_stream* inp) { return inp->cur == inp->end; }
319 
320 ////////////////////////////////////////////////////////////////////////////////
321 // dns resolution
322 
323 typedef struct addr_req {
324   grpc_timer timer;
325   char* addr;
326   grpc_closure* on_done;
327   grpc_resolved_addresses** addrs;
328   grpc_lb_addresses** lb_addrs;
329 } addr_req;
330 
finish_resolve(void * arg,grpc_error * error)331 static void finish_resolve(void* arg, grpc_error* error) {
332   addr_req* r = static_cast<addr_req*>(arg);
333 
334   if (error == GRPC_ERROR_NONE && 0 == strcmp(r->addr, "server")) {
335     if (r->addrs != nullptr) {
336       grpc_resolved_addresses* addrs =
337           static_cast<grpc_resolved_addresses*>(gpr_malloc(sizeof(*addrs)));
338       addrs->naddrs = 1;
339       addrs->addrs = static_cast<grpc_resolved_address*>(
340           gpr_malloc(sizeof(*addrs->addrs)));
341       addrs->addrs[0].len = 0;
342       *r->addrs = addrs;
343     } else if (r->lb_addrs != nullptr) {
344       grpc_lb_addresses* lb_addrs = grpc_lb_addresses_create(1, nullptr);
345       grpc_lb_addresses_set_address(lb_addrs, 0, nullptr, 0, false, nullptr,
346                                     nullptr);
347       *r->lb_addrs = lb_addrs;
348     }
349     GRPC_CLOSURE_SCHED(r->on_done, GRPC_ERROR_NONE);
350   } else {
351     GRPC_CLOSURE_SCHED(r->on_done,
352                        GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
353                            "Resolution failed", &error, 1));
354   }
355 
356   gpr_free(r->addr);
357   gpr_free(r);
358 }
359 
my_resolve_address(const char * addr,const char * default_port,grpc_pollset_set * interested_parties,grpc_closure * on_done,grpc_resolved_addresses ** addresses)360 void my_resolve_address(const char* addr, const char* default_port,
361                         grpc_pollset_set* interested_parties,
362                         grpc_closure* on_done,
363                         grpc_resolved_addresses** addresses) {
364   addr_req* r = static_cast<addr_req*>(gpr_malloc(sizeof(*r)));
365   r->addr = gpr_strdup(addr);
366   r->on_done = on_done;
367   r->addrs = addresses;
368   r->lb_addrs = nullptr;
369   grpc_timer_init(
370       &r->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(),
371       GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx));
372 }
373 
374 static grpc_address_resolver_vtable fuzzer_resolver = {my_resolve_address,
375                                                        nullptr};
376 
my_dns_lookup_ares_locked(const char * dns_server,const char * addr,const char * default_port,grpc_pollset_set * interested_parties,grpc_closure * on_done,grpc_lb_addresses ** lb_addrs,bool check_grpclb,char ** service_config_json,grpc_combiner * combiner)377 grpc_ares_request* my_dns_lookup_ares_locked(
378     const char* dns_server, const char* addr, const char* default_port,
379     grpc_pollset_set* interested_parties, grpc_closure* on_done,
380     grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json,
381     grpc_combiner* combiner) {
382   addr_req* r = static_cast<addr_req*>(gpr_malloc(sizeof(*r)));
383   r->addr = gpr_strdup(addr);
384   r->on_done = on_done;
385   r->addrs = nullptr;
386   r->lb_addrs = lb_addrs;
387   grpc_timer_init(
388       &r->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(),
389       GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx));
390   return nullptr;
391 }
392 
393 ////////////////////////////////////////////////////////////////////////////////
394 // client connection
395 
396 static void sched_connect(grpc_closure* closure, grpc_endpoint** ep,
397                           gpr_timespec deadline);
398 
399 typedef struct {
400   grpc_timer timer;
401   grpc_closure* closure;
402   grpc_endpoint** ep;
403   gpr_timespec deadline;
404 } future_connect;
405 
do_connect(void * arg,grpc_error * error)406 static void do_connect(void* arg, grpc_error* error) {
407   future_connect* fc = static_cast<future_connect*>(arg);
408   if (error != GRPC_ERROR_NONE) {
409     *fc->ep = nullptr;
410     GRPC_CLOSURE_SCHED(fc->closure, GRPC_ERROR_REF(error));
411   } else if (g_server != nullptr) {
412     grpc_endpoint* client;
413     grpc_endpoint* server;
414     grpc_passthru_endpoint_create(&client, &server, g_resource_quota, nullptr);
415     *fc->ep = client;
416 
417     grpc_transport* transport =
418         grpc_create_chttp2_transport(nullptr, server, false);
419     grpc_server_setup_transport(g_server, transport, nullptr, nullptr);
420     grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
421 
422     GRPC_CLOSURE_SCHED(fc->closure, GRPC_ERROR_NONE);
423   } else {
424     sched_connect(fc->closure, fc->ep, fc->deadline);
425   }
426   gpr_free(fc);
427 }
428 
sched_connect(grpc_closure * closure,grpc_endpoint ** ep,gpr_timespec deadline)429 static void sched_connect(grpc_closure* closure, grpc_endpoint** ep,
430                           gpr_timespec deadline) {
431   if (gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) < 0) {
432     *ep = nullptr;
433     GRPC_CLOSURE_SCHED(closure, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
434                                     "Connect deadline exceeded"));
435     return;
436   }
437 
438   future_connect* fc = static_cast<future_connect*>(gpr_malloc(sizeof(*fc)));
439   fc->closure = closure;
440   fc->ep = ep;
441   fc->deadline = deadline;
442   grpc_timer_init(
443       &fc->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(),
444       GRPC_CLOSURE_CREATE(do_connect, fc, grpc_schedule_on_exec_ctx));
445 }
446 
my_tcp_client_connect(grpc_closure * closure,grpc_endpoint ** ep,grpc_pollset_set * interested_parties,const grpc_channel_args * channel_args,const grpc_resolved_address * addr,grpc_millis deadline)447 static void my_tcp_client_connect(grpc_closure* closure, grpc_endpoint** ep,
448                                   grpc_pollset_set* interested_parties,
449                                   const grpc_channel_args* channel_args,
450                                   const grpc_resolved_address* addr,
451                                   grpc_millis deadline) {
452   sched_connect(closure, ep,
453                 grpc_millis_to_timespec(deadline, GPR_CLOCK_MONOTONIC));
454 }
455 
456 grpc_tcp_client_vtable fuzz_tcp_client_vtable = {my_tcp_client_connect};
457 
458 ////////////////////////////////////////////////////////////////////////////////
459 // test driver
460 
461 typedef struct validator {
462   void (*validate)(void* arg, bool success);
463   void* arg;
464 } validator;
465 
create_validator(void (* validate)(void * arg,bool success),void * arg)466 static validator* create_validator(void (*validate)(void* arg, bool success),
467                                    void* arg) {
468   validator* v = static_cast<validator*>(gpr_malloc(sizeof(*v)));
469   v->validate = validate;
470   v->arg = arg;
471   return v;
472 }
473 
assert_success_and_decrement(void * counter,bool success)474 static void assert_success_and_decrement(void* counter, bool success) {
475   GPR_ASSERT(success);
476   --*static_cast<int*>(counter);
477 }
478 
decrement(void * counter,bool success)479 static void decrement(void* counter, bool success) {
480   --*static_cast<int*>(counter);
481 }
482 
483 typedef struct connectivity_watch {
484   int* counter;
485   gpr_timespec deadline;
486 } connectivity_watch;
487 
make_connectivity_watch(gpr_timespec s,int * counter)488 static connectivity_watch* make_connectivity_watch(gpr_timespec s,
489                                                    int* counter) {
490   connectivity_watch* o =
491       static_cast<connectivity_watch*>(gpr_malloc(sizeof(*o)));
492   o->deadline = s;
493   o->counter = counter;
494   return o;
495 }
496 
validate_connectivity_watch(void * p,bool success)497 static void validate_connectivity_watch(void* p, bool success) {
498   connectivity_watch* w = static_cast<connectivity_watch*>(p);
499   if (!success) {
500     GPR_ASSERT(gpr_time_cmp(gpr_now(w->deadline.clock_type), w->deadline) >= 0);
501   }
502   --*w->counter;
503   gpr_free(w);
504 }
505 
free_non_null(void * p)506 static void free_non_null(void* p) {
507   GPR_ASSERT(p != nullptr);
508   gpr_free(p);
509 }
510 
511 typedef enum { ROOT, CLIENT, SERVER, PENDING_SERVER } call_state_type;
512 
513 #define DONE_FLAG_CALL_CLOSED ((uint64_t)(1 << 0))
514 
515 typedef struct call_state {
516   call_state_type type;
517   grpc_call* call;
518   grpc_byte_buffer* recv_message;
519   grpc_status_code status;
520   grpc_metadata_array recv_initial_metadata;
521   grpc_metadata_array recv_trailing_metadata;
522   grpc_slice recv_status_details;
523   int cancelled;
524   int pending_ops;
525   bool sent_initial_metadata;
526   grpc_call_details call_details;
527   grpc_byte_buffer* send_message;
528   // starts at 0, individual flags from DONE_FLAG_xxx are set
529   // as different operations are completed
530   uint64_t done_flags;
531 
532   // array of pointers to free later
533   size_t num_to_free;
534   size_t cap_to_free;
535   void** to_free;
536 
537   // array of slices to unref
538   size_t num_slices_to_unref;
539   size_t cap_slices_to_unref;
540   grpc_slice** slices_to_unref;
541 
542   struct call_state* next;
543   struct call_state* prev;
544 } call_state;
545 
546 static call_state* g_active_call;
547 
new_call(call_state * sibling,call_state_type type)548 static call_state* new_call(call_state* sibling, call_state_type type) {
549   call_state* c = static_cast<call_state*>(gpr_malloc(sizeof(*c)));
550   memset(c, 0, sizeof(*c));
551   if (sibling != nullptr) {
552     c->next = sibling;
553     c->prev = sibling->prev;
554     c->next->prev = c->prev->next = c;
555   } else {
556     c->next = c->prev = c;
557   }
558   c->type = type;
559   return c;
560 }
561 
maybe_delete_call_state(call_state * call)562 static call_state* maybe_delete_call_state(call_state* call) {
563   call_state* next = call->next;
564 
565   if (call->call != nullptr) return next;
566   if (call->pending_ops != 0) return next;
567 
568   if (call == g_active_call) {
569     g_active_call = call->next;
570     GPR_ASSERT(call != g_active_call);
571   }
572 
573   call->prev->next = call->next;
574   call->next->prev = call->prev;
575   grpc_metadata_array_destroy(&call->recv_initial_metadata);
576   grpc_metadata_array_destroy(&call->recv_trailing_metadata);
577   grpc_slice_unref(call->recv_status_details);
578   grpc_call_details_destroy(&call->call_details);
579 
580   for (size_t i = 0; i < call->num_slices_to_unref; i++) {
581     grpc_slice_unref(*call->slices_to_unref[i]);
582     gpr_free(call->slices_to_unref[i]);
583   }
584   for (size_t i = 0; i < call->num_to_free; i++) {
585     gpr_free(call->to_free[i]);
586   }
587   gpr_free(call->to_free);
588   gpr_free(call->slices_to_unref);
589 
590   gpr_free(call);
591 
592   return next;
593 }
594 
add_to_free(call_state * call,void * p)595 static void add_to_free(call_state* call, void* p) {
596   if (call->num_to_free == call->cap_to_free) {
597     call->cap_to_free = GPR_MAX(8, 2 * call->cap_to_free);
598     call->to_free = static_cast<void**>(
599         gpr_realloc(call->to_free, sizeof(*call->to_free) * call->cap_to_free));
600   }
601   call->to_free[call->num_to_free++] = p;
602 }
603 
add_slice_to_unref(call_state * call,grpc_slice s)604 static grpc_slice* add_slice_to_unref(call_state* call, grpc_slice s) {
605   if (call->num_slices_to_unref == call->cap_slices_to_unref) {
606     call->cap_slices_to_unref = GPR_MAX(8, 2 * call->cap_slices_to_unref);
607     call->slices_to_unref = static_cast<grpc_slice**>(gpr_realloc(
608         call->slices_to_unref,
609         sizeof(*call->slices_to_unref) * call->cap_slices_to_unref));
610   }
611   call->slices_to_unref[call->num_slices_to_unref] =
612       static_cast<grpc_slice*>(gpr_malloc(sizeof(grpc_slice)));
613   *call->slices_to_unref[call->num_slices_to_unref++] = s;
614   return call->slices_to_unref[call->num_slices_to_unref - 1];
615 }
616 
read_metadata(input_stream * inp,size_t * count,grpc_metadata ** metadata,call_state * cs)617 static void read_metadata(input_stream* inp, size_t* count,
618                           grpc_metadata** metadata, call_state* cs) {
619   *count = grpc_fuzzer_get_next_byte(inp);
620   if (*count) {
621     *metadata =
622         static_cast<grpc_metadata*>(gpr_malloc(*count * sizeof(**metadata)));
623     memset(*metadata, 0, *count * sizeof(**metadata));
624     for (size_t i = 0; i < *count; i++) {
625       (*metadata)[i].key = read_string_like_slice(inp);
626       (*metadata)[i].value = read_buffer_like_slice(inp);
627       (*metadata)[i].flags = grpc_fuzzer_get_next_uint32(inp);
628       add_slice_to_unref(cs, (*metadata)[i].key);
629       add_slice_to_unref(cs, (*metadata)[i].value);
630     }
631   } else {
632     *metadata = static_cast<grpc_metadata*>(gpr_malloc(1));
633   }
634   add_to_free(cs, *metadata);
635 }
636 
destroy_call(call_state * call)637 static call_state* destroy_call(call_state* call) {
638   grpc_call_unref(call->call);
639   call->call = nullptr;
640   return maybe_delete_call_state(call);
641 }
642 
finished_request_call(void * csp,bool success)643 static void finished_request_call(void* csp, bool success) {
644   call_state* cs = static_cast<call_state*>(csp);
645   GPR_ASSERT(cs->pending_ops > 0);
646   --cs->pending_ops;
647   if (success) {
648     GPR_ASSERT(cs->call != nullptr);
649     cs->type = SERVER;
650   } else {
651     maybe_delete_call_state(cs);
652   }
653 }
654 
655 typedef struct {
656   call_state* cs;
657   uint8_t has_ops;
658 } batch_info;
659 
finished_batch(void * p,bool success)660 static void finished_batch(void* p, bool success) {
661   batch_info* bi = static_cast<batch_info*>(p);
662   --bi->cs->pending_ops;
663   if ((bi->has_ops & (1u << GRPC_OP_RECV_MESSAGE)) &&
664       (bi->cs->done_flags & DONE_FLAG_CALL_CLOSED)) {
665     GPR_ASSERT(bi->cs->recv_message == nullptr);
666   }
667   if ((bi->has_ops & (1u << GRPC_OP_RECV_MESSAGE) &&
668        bi->cs->recv_message != nullptr)) {
669     grpc_byte_buffer_destroy(bi->cs->recv_message);
670     bi->cs->recv_message = nullptr;
671   }
672   if ((bi->has_ops & (1u << GRPC_OP_SEND_MESSAGE))) {
673     grpc_byte_buffer_destroy(bi->cs->send_message);
674     bi->cs->send_message = nullptr;
675   }
676   if ((bi->has_ops & (1u << GRPC_OP_RECV_STATUS_ON_CLIENT)) ||
677       (bi->has_ops & (1u << GRPC_OP_RECV_CLOSE_ON_SERVER))) {
678     bi->cs->done_flags |= DONE_FLAG_CALL_CLOSED;
679   }
680   maybe_delete_call_state(bi->cs);
681   gpr_free(bi);
682 }
683 
make_finished_batch_validator(call_state * cs,uint8_t has_ops)684 static validator* make_finished_batch_validator(call_state* cs,
685                                                 uint8_t has_ops) {
686   batch_info* bi = static_cast<batch_info*>(gpr_malloc(sizeof(*bi)));
687   bi->cs = cs;
688   bi->has_ops = has_ops;
689   return create_validator(finished_batch, bi);
690 }
691 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)692 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
693   grpc_test_only_set_slice_hash_seed(0);
694   char* grpc_trace_fuzzer = gpr_getenv("GRPC_TRACE_FUZZER");
695   if (squelch && grpc_trace_fuzzer == nullptr) gpr_set_log_function(dont_log);
696   gpr_free(grpc_trace_fuzzer);
697   input_stream inp = {data, data + size};
698   grpc_set_tcp_client_impl(&fuzz_tcp_client_vtable);
699   gpr_now_impl = now_impl;
700   grpc_init();
701   grpc_timer_manager_set_threading(false);
702   {
703     grpc_core::ExecCtx exec_ctx;
704     grpc_executor_set_threading(false);
705   }
706   grpc_set_resolver_impl(&fuzzer_resolver);
707   grpc_dns_lookup_ares_locked = my_dns_lookup_ares_locked;
708 
709   GPR_ASSERT(g_channel == nullptr);
710   GPR_ASSERT(g_server == nullptr);
711 
712   bool server_shutdown = false;
713   int pending_server_shutdowns = 0;
714   int pending_channel_watches = 0;
715   int pending_pings = 0;
716 
717   g_active_call = new_call(nullptr, ROOT);
718   g_resource_quota = grpc_resource_quota_create("api_fuzzer");
719 
720   grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr);
721 
722   while (!is_eof(&inp) || g_channel != nullptr || g_server != nullptr ||
723          pending_channel_watches > 0 || pending_pings > 0 ||
724          g_active_call->type != ROOT || g_active_call->next != g_active_call) {
725     if (is_eof(&inp)) {
726       if (g_channel != nullptr) {
727         grpc_channel_destroy(g_channel);
728         g_channel = nullptr;
729       }
730       if (g_server != nullptr) {
731         if (!server_shutdown) {
732           grpc_server_shutdown_and_notify(
733               g_server, cq,
734               create_validator(assert_success_and_decrement,
735                                &pending_server_shutdowns));
736           server_shutdown = true;
737           pending_server_shutdowns++;
738         } else if (pending_server_shutdowns == 0) {
739           grpc_server_destroy(g_server);
740           g_server = nullptr;
741         }
742       }
743       call_state* s = g_active_call;
744       do {
745         if (s->type != PENDING_SERVER && s->call != nullptr) {
746           s = destroy_call(s);
747         } else {
748           s = s->next;
749         }
750       } while (s != g_active_call);
751 
752       g_now = gpr_time_add(g_now, gpr_time_from_seconds(1, GPR_TIMESPAN));
753     }
754 
755     grpc_timer_manager_tick();
756 
757     switch (grpc_fuzzer_get_next_byte(&inp)) {
758       // terminate on bad bytes
759       default:
760         end(&inp);
761         break;
762       // tickle completion queue
763       case 0: {
764         grpc_event ev = grpc_completion_queue_next(
765             cq, gpr_inf_past(GPR_CLOCK_REALTIME), nullptr);
766         switch (ev.type) {
767           case GRPC_OP_COMPLETE: {
768             validator* v = static_cast<validator*>(ev.tag);
769             v->validate(v->arg, ev.success);
770             gpr_free(v);
771             break;
772           }
773           case GRPC_QUEUE_TIMEOUT:
774             break;
775           case GRPC_QUEUE_SHUTDOWN:
776             abort();
777             break;
778         }
779         break;
780       }
781       // increment global time
782       case 1: {
783         g_now = gpr_time_add(
784             g_now, gpr_time_from_micros(grpc_fuzzer_get_next_uint32(&inp),
785                                         GPR_TIMESPAN));
786         break;
787       }
788       // create an insecure channel
789       case 2: {
790         if (g_channel == nullptr) {
791           char* target = grpc_fuzzer_get_next_string(&inp, nullptr);
792           char* target_uri;
793           gpr_asprintf(&target_uri, "dns:%s", target);
794           grpc_channel_args* args = read_args(&inp);
795           g_channel = grpc_insecure_channel_create(target_uri, args, nullptr);
796           GPR_ASSERT(g_channel != nullptr);
797           {
798             grpc_core::ExecCtx exec_ctx;
799             grpc_channel_args_destroy(args);
800           }
801           gpr_free(target_uri);
802           gpr_free(target);
803         } else {
804           end(&inp);
805         }
806         break;
807       }
808       // destroy a channel
809       case 3: {
810         if (g_channel != nullptr) {
811           grpc_channel_destroy(g_channel);
812           g_channel = nullptr;
813         } else {
814           end(&inp);
815         }
816         break;
817       }
818       // bring up a server
819       case 4: {
820         if (g_server == nullptr) {
821           grpc_channel_args* args = read_args(&inp);
822           g_server = grpc_server_create(args, nullptr);
823           GPR_ASSERT(g_server != nullptr);
824           {
825             grpc_core::ExecCtx exec_ctx;
826             grpc_channel_args_destroy(args);
827           }
828           grpc_server_register_completion_queue(g_server, cq, nullptr);
829           grpc_server_start(g_server);
830           server_shutdown = false;
831           GPR_ASSERT(pending_server_shutdowns == 0);
832         } else {
833           end(&inp);
834         }
835         break;
836       }
837       // begin server shutdown
838       case 5: {
839         if (g_server != nullptr) {
840           grpc_server_shutdown_and_notify(
841               g_server, cq,
842               create_validator(assert_success_and_decrement,
843                                &pending_server_shutdowns));
844           pending_server_shutdowns++;
845           server_shutdown = true;
846         } else {
847           end(&inp);
848         }
849         break;
850       }
851       // cancel all calls if shutdown
852       case 6: {
853         if (g_server != nullptr && server_shutdown) {
854           grpc_server_cancel_all_calls(g_server);
855         } else {
856           end(&inp);
857         }
858         break;
859       }
860       // destroy server
861       case 7: {
862         if (g_server != nullptr && server_shutdown &&
863             pending_server_shutdowns == 0) {
864           grpc_server_destroy(g_server);
865           g_server = nullptr;
866         } else {
867           end(&inp);
868         }
869         break;
870       }
871       // check connectivity
872       case 8: {
873         if (g_channel != nullptr) {
874           uint8_t try_to_connect = grpc_fuzzer_get_next_byte(&inp);
875           if (try_to_connect == 0 || try_to_connect == 1) {
876             grpc_channel_check_connectivity_state(g_channel, try_to_connect);
877           } else {
878             end(&inp);
879           }
880         } else {
881           end(&inp);
882         }
883         break;
884       }
885       // watch connectivity
886       case 9: {
887         if (g_channel != nullptr) {
888           grpc_connectivity_state st =
889               grpc_channel_check_connectivity_state(g_channel, 0);
890           if (st != GRPC_CHANNEL_SHUTDOWN) {
891             gpr_timespec deadline = gpr_time_add(
892                 gpr_now(GPR_CLOCK_REALTIME),
893                 gpr_time_from_micros(grpc_fuzzer_get_next_uint32(&inp),
894                                      GPR_TIMESPAN));
895             grpc_channel_watch_connectivity_state(
896                 g_channel, st, deadline, cq,
897                 create_validator(validate_connectivity_watch,
898                                  make_connectivity_watch(
899                                      deadline, &pending_channel_watches)));
900             pending_channel_watches++;
901           }
902         } else {
903           end(&inp);
904         }
905         break;
906       }
907       // create a call
908       case 10: {
909         bool ok = true;
910         if (g_channel == nullptr) ok = false;
911         grpc_call* parent_call = nullptr;
912         if (g_active_call->type != ROOT) {
913           if (g_active_call->call == nullptr || g_active_call->type == CLIENT) {
914             end(&inp);
915             break;
916           }
917           parent_call = g_active_call->call;
918         }
919         uint32_t propagation_mask = grpc_fuzzer_get_next_uint32(&inp);
920         grpc_slice method = read_string_like_slice(&inp);
921         if (GRPC_SLICE_LENGTH(method) == 0) {
922           ok = false;
923         }
924         grpc_slice host = read_string_like_slice(&inp);
925         gpr_timespec deadline =
926             gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
927                          gpr_time_from_micros(grpc_fuzzer_get_next_uint32(&inp),
928                                               GPR_TIMESPAN));
929 
930         if (ok) {
931           call_state* cs = new_call(g_active_call, CLIENT);
932           cs->call =
933               grpc_channel_create_call(g_channel, parent_call, propagation_mask,
934                                        cq, method, &host, deadline, nullptr);
935         } else {
936           end(&inp);
937         }
938         grpc_slice_unref(method);
939         grpc_slice_unref(host);
940         break;
941       }
942       // switch the 'current' call
943       case 11: {
944         g_active_call = g_active_call->next;
945         break;
946       }
947       // queue some ops on a call
948       case 12: {
949         if (g_active_call->type == PENDING_SERVER ||
950             g_active_call->type == ROOT || g_active_call->call == nullptr) {
951           end(&inp);
952           break;
953         }
954         size_t num_ops = grpc_fuzzer_get_next_byte(&inp);
955         if (num_ops > 6) {
956           end(&inp);
957           break;
958         }
959         grpc_op* ops =
960             static_cast<grpc_op*>(gpr_malloc(sizeof(grpc_op) * num_ops));
961         if (num_ops > 0) memset(ops, 0, sizeof(grpc_op) * num_ops);
962         bool ok = true;
963         size_t i;
964         grpc_op* op;
965         uint8_t has_ops = 0;
966         for (i = 0; i < num_ops; i++) {
967           op = &ops[i];
968           switch (grpc_fuzzer_get_next_byte(&inp)) {
969             default:
970               /* invalid value */
971               op->op = (grpc_op_type)-1;
972               ok = false;
973               break;
974             case GRPC_OP_SEND_INITIAL_METADATA:
975               if (g_active_call->sent_initial_metadata) {
976                 ok = false;
977               } else {
978                 g_active_call->sent_initial_metadata = true;
979                 op->op = GRPC_OP_SEND_INITIAL_METADATA;
980                 has_ops |= 1 << GRPC_OP_SEND_INITIAL_METADATA;
981                 read_metadata(&inp, &op->data.send_initial_metadata.count,
982                               &op->data.send_initial_metadata.metadata,
983                               g_active_call);
984               }
985               break;
986             case GRPC_OP_SEND_MESSAGE:
987               op->op = GRPC_OP_SEND_MESSAGE;
988               if (g_active_call->send_message != nullptr) {
989                 ok = false;
990               } else {
991                 has_ops |= 1 << GRPC_OP_SEND_MESSAGE;
992                 g_active_call->send_message =
993                     op->data.send_message.send_message = read_message(&inp);
994               }
995               break;
996             case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
997               op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
998               has_ops |= 1 << GRPC_OP_SEND_CLOSE_FROM_CLIENT;
999               break;
1000             case GRPC_OP_SEND_STATUS_FROM_SERVER:
1001               op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
1002               has_ops |= 1 << GRPC_OP_SEND_STATUS_FROM_SERVER;
1003               read_metadata(
1004                   &inp,
1005                   &op->data.send_status_from_server.trailing_metadata_count,
1006                   &op->data.send_status_from_server.trailing_metadata,
1007                   g_active_call);
1008               op->data.send_status_from_server.status =
1009                   static_cast<grpc_status_code>(
1010                       grpc_fuzzer_get_next_byte(&inp));
1011               op->data.send_status_from_server.status_details =
1012                   add_slice_to_unref(g_active_call,
1013                                      read_buffer_like_slice(&inp));
1014               break;
1015             case GRPC_OP_RECV_INITIAL_METADATA:
1016               op->op = GRPC_OP_RECV_INITIAL_METADATA;
1017               has_ops |= 1 << GRPC_OP_RECV_INITIAL_METADATA;
1018               op->data.recv_initial_metadata.recv_initial_metadata =
1019                   &g_active_call->recv_initial_metadata;
1020               break;
1021             case GRPC_OP_RECV_MESSAGE:
1022               if (g_active_call->done_flags & DONE_FLAG_CALL_CLOSED) {
1023                 ok = false;
1024               } else {
1025                 op->op = GRPC_OP_RECV_MESSAGE;
1026                 has_ops |= 1 << GRPC_OP_RECV_MESSAGE;
1027                 op->data.recv_message.recv_message =
1028                     &g_active_call->recv_message;
1029               }
1030               break;
1031             case GRPC_OP_RECV_STATUS_ON_CLIENT:
1032               op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
1033               op->data.recv_status_on_client.status = &g_active_call->status;
1034               op->data.recv_status_on_client.trailing_metadata =
1035                   &g_active_call->recv_trailing_metadata;
1036               op->data.recv_status_on_client.status_details =
1037                   &g_active_call->recv_status_details;
1038               break;
1039             case GRPC_OP_RECV_CLOSE_ON_SERVER:
1040               op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
1041               has_ops |= 1 << GRPC_OP_RECV_CLOSE_ON_SERVER;
1042               op->data.recv_close_on_server.cancelled =
1043                   &g_active_call->cancelled;
1044               break;
1045           }
1046           op->reserved = nullptr;
1047           op->flags = grpc_fuzzer_get_next_uint32(&inp);
1048         }
1049         if (g_channel == nullptr) ok = false;
1050         if (ok) {
1051           validator* v = make_finished_batch_validator(g_active_call, has_ops);
1052           g_active_call->pending_ops++;
1053           grpc_call_error error = grpc_call_start_batch(
1054               g_active_call->call, ops, num_ops, v, nullptr);
1055           if (error != GRPC_CALL_OK) {
1056             v->validate(v->arg, false);
1057             gpr_free(v);
1058           }
1059         } else {
1060           end(&inp);
1061         }
1062         if (!ok && (has_ops & (1 << GRPC_OP_SEND_MESSAGE))) {
1063           grpc_byte_buffer_destroy(g_active_call->send_message);
1064           g_active_call->send_message = nullptr;
1065         }
1066         gpr_free(ops);
1067 
1068         break;
1069       }
1070       // cancel current call
1071       case 13: {
1072         if (g_active_call->type != ROOT && g_active_call->call != nullptr) {
1073           grpc_call_cancel(g_active_call->call, nullptr);
1074         } else {
1075           end(&inp);
1076         }
1077         break;
1078       }
1079       // get a calls peer
1080       case 14: {
1081         if (g_active_call->type != ROOT && g_active_call->call != nullptr) {
1082           free_non_null(grpc_call_get_peer(g_active_call->call));
1083         } else {
1084           end(&inp);
1085         }
1086         break;
1087       }
1088       // get a channels target
1089       case 15: {
1090         if (g_channel != nullptr) {
1091           free_non_null(grpc_channel_get_target(g_channel));
1092         } else {
1093           end(&inp);
1094         }
1095         break;
1096       }
1097       // send a ping on a channel
1098       case 16: {
1099         if (g_channel != nullptr) {
1100           pending_pings++;
1101           grpc_channel_ping(g_channel, cq,
1102                             create_validator(decrement, &pending_pings),
1103                             nullptr);
1104         } else {
1105           end(&inp);
1106         }
1107         break;
1108       }
1109       // enable a tracer
1110       case 17: {
1111         char* tracer = grpc_fuzzer_get_next_string(&inp, nullptr);
1112         grpc_tracer_set_enabled(tracer, 1);
1113         gpr_free(tracer);
1114         break;
1115       }
1116       // disable a tracer
1117       case 18: {
1118         char* tracer = grpc_fuzzer_get_next_string(&inp, nullptr);
1119         grpc_tracer_set_enabled(tracer, 0);
1120         gpr_free(tracer);
1121         break;
1122       }
1123       // request a server call
1124       case 19: {
1125         if (g_server == nullptr) {
1126           end(&inp);
1127           break;
1128         }
1129         call_state* cs = new_call(g_active_call, PENDING_SERVER);
1130         cs->pending_ops++;
1131         validator* v = create_validator(finished_request_call, cs);
1132         grpc_call_error error =
1133             grpc_server_request_call(g_server, &cs->call, &cs->call_details,
1134                                      &cs->recv_initial_metadata, cq, cq, v);
1135         if (error != GRPC_CALL_OK) {
1136           v->validate(v->arg, false);
1137           gpr_free(v);
1138         }
1139         break;
1140       }
1141       // destroy a call
1142       case 20: {
1143         if (g_active_call->type != ROOT &&
1144             g_active_call->type != PENDING_SERVER &&
1145             g_active_call->call != nullptr) {
1146           destroy_call(g_active_call);
1147         } else {
1148           end(&inp);
1149         }
1150         break;
1151       }
1152       // resize the buffer pool
1153       case 21: {
1154         grpc_resource_quota_resize(g_resource_quota, read_uint22(&inp));
1155         break;
1156       }
1157       // create a secure channel
1158       case 22: {
1159         if (g_channel == nullptr) {
1160           char* target = grpc_fuzzer_get_next_string(&inp, nullptr);
1161           char* target_uri;
1162           gpr_asprintf(&target_uri, "dns:%s", target);
1163           grpc_channel_args* args = read_args(&inp);
1164           grpc_channel_credentials* creds = read_channel_creds(&inp);
1165           g_channel =
1166               grpc_secure_channel_create(creds, target_uri, args, nullptr);
1167           GPR_ASSERT(g_channel != nullptr);
1168           {
1169             grpc_core::ExecCtx exec_ctx;
1170             grpc_channel_args_destroy(args);
1171           }
1172           gpr_free(target_uri);
1173           gpr_free(target);
1174           grpc_channel_credentials_release(creds);
1175         } else {
1176           end(&inp);
1177         }
1178         break;
1179       }
1180     }
1181   }
1182 
1183   GPR_ASSERT(g_channel == nullptr);
1184   GPR_ASSERT(g_server == nullptr);
1185   GPR_ASSERT(g_active_call->type == ROOT);
1186   GPR_ASSERT(g_active_call->next == g_active_call);
1187   gpr_free(g_active_call);
1188 
1189   grpc_completion_queue_shutdown(cq);
1190   GPR_ASSERT(
1191       grpc_completion_queue_next(cq, gpr_inf_past(GPR_CLOCK_REALTIME), nullptr)
1192           .type == GRPC_QUEUE_SHUTDOWN);
1193   grpc_completion_queue_destroy(cq);
1194 
1195   grpc_resource_quota_unref(g_resource_quota);
1196 
1197   grpc_shutdown();
1198   return 0;
1199 }
1200