mirror of https://github.com/grpc/grpc.git
parent
3b476d4d3e
commit
31e2128571
5 changed files with 316 additions and 0 deletions
@ -0,0 +1,154 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#include <grpc/grpc.h> |
||||
#include <grpc/grpc_security.h> |
||||
#include <grpc/support/log.h> |
||||
|
||||
#include "src/core/lib/iomgr/load_file.h" |
||||
#include "src/core/lib/security/credentials/credentials.h" |
||||
#include "src/core/lib/security/transport/security_connector.h" |
||||
#include "test/core/util/memory_counters.h" |
||||
#include "test/core/util/mock_endpoint.h" |
||||
|
||||
bool squelch = true; |
||||
// ssl has an array of global gpr_mu's that are never released.
|
||||
// Turning this on will fail the leak check.
|
||||
bool leak_check = false; |
||||
|
||||
#define SSL_CERT_PATH "src/core/lib/tsi/test_creds/server1.pem" |
||||
#define SSL_KEY_PATH "src/core/lib/tsi/test_creds/server1.key" |
||||
#define SSL_CA_PATH "src/core/lib/tsi/test_creds/ca.pem" |
||||
|
||||
static void discard_write(gpr_slice slice) {} |
||||
|
||||
static void dont_log(gpr_log_func_args *args) {} |
||||
|
||||
struct handshake_state { |
||||
bool done_callback_called; |
||||
}; |
||||
|
||||
static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, |
||||
grpc_security_status status, |
||||
grpc_endpoint *secure_endpoint, |
||||
grpc_auth_context *auth_context) { |
||||
struct handshake_state *state = (struct handshake_state *)statep; |
||||
GPR_ASSERT(state->done_callback_called == false); |
||||
state->done_callback_called = true; |
||||
// The fuzzer should not pass the handshake.
|
||||
GPR_ASSERT(status != GRPC_SECURITY_OK); |
||||
GPR_ASSERT(secure_endpoint == NULL); |
||||
GPR_ASSERT(auth_context == NULL); |
||||
} |
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
||||
struct grpc_memory_counters counters; |
||||
if (squelch) gpr_set_log_function(dont_log); |
||||
if (leak_check) grpc_memory_counters_init(); |
||||
grpc_init(); |
||||
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
||||
|
||||
grpc_resource_quota *resource_quota = |
||||
grpc_resource_quota_create("ssl_server_fuzzer"); |
||||
grpc_endpoint *mock_endpoint = |
||||
grpc_mock_endpoint_create(discard_write, resource_quota); |
||||
grpc_resource_quota_internal_unref(&exec_ctx, resource_quota); |
||||
|
||||
grpc_mock_endpoint_put_read( |
||||
&exec_ctx, mock_endpoint, |
||||
gpr_slice_from_copied_buffer((const char *)data, size)); |
||||
|
||||
// Load key pair and establish server SSL credentials.
|
||||
grpc_ssl_pem_key_cert_pair pem_key_cert_pair; |
||||
gpr_slice ca_slice, cert_slice, key_slice; |
||||
GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", |
||||
grpc_load_file(SSL_CA_PATH, 1, &ca_slice))); |
||||
GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", |
||||
grpc_load_file(SSL_CERT_PATH, 1, &cert_slice))); |
||||
GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", |
||||
grpc_load_file(SSL_KEY_PATH, 1, &key_slice))); |
||||
const char *ca_cert = (const char *)GPR_SLICE_START_PTR(ca_slice); |
||||
pem_key_cert_pair.private_key = (const char *)GPR_SLICE_START_PTR(key_slice); |
||||
pem_key_cert_pair.cert_chain = (const char *)GPR_SLICE_START_PTR(cert_slice); |
||||
grpc_server_credentials *creds = grpc_ssl_server_credentials_create( |
||||
ca_cert, &pem_key_cert_pair, 1, 0, NULL); |
||||
|
||||
// Create security connector
|
||||
grpc_server_security_connector *sc = NULL; |
||||
grpc_security_status status = |
||||
grpc_server_credentials_create_security_connector(creds, &sc); |
||||
GPR_ASSERT(status == GRPC_SECURITY_OK); |
||||
sc->channel_args = NULL; |
||||
gpr_timespec deadline = gpr_time_add( |
||||
gpr_now(GPR_CLOCK_MONOTONIC), |
||||
gpr_time_from_seconds(1, GPR_TIMESPAN)); |
||||
|
||||
struct handshake_state state; |
||||
state.done_callback_called = false; |
||||
grpc_server_security_connector_do_handshake( |
||||
&exec_ctx, sc, NULL, mock_endpoint, NULL, deadline, |
||||
on_secure_handshake_done, &state); |
||||
grpc_exec_ctx_flush(&exec_ctx); |
||||
|
||||
bool mock_endpoint_shutdown = false; |
||||
// If the given string happens to be part of the correct client hello, the
|
||||
// server will wait for more data. Explicitly fail the server by shutting down
|
||||
// the endpoint.
|
||||
if (!state.done_callback_called) { |
||||
mock_endpoint_shutdown = true; |
||||
grpc_endpoint_shutdown(&exec_ctx, mock_endpoint); |
||||
grpc_exec_ctx_flush(&exec_ctx); |
||||
} |
||||
|
||||
GPR_ASSERT(state.done_callback_called); |
||||
|
||||
GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "test"); |
||||
grpc_server_credentials_release(creds); |
||||
gpr_slice_unref(cert_slice); |
||||
gpr_slice_unref(key_slice); |
||||
gpr_slice_unref(ca_slice); |
||||
// grpc_endpoint_destroy has been called in handshake failure handling code.
|
||||
if (!mock_endpoint_shutdown) { |
||||
grpc_endpoint_shutdown(&exec_ctx, mock_endpoint); |
||||
grpc_exec_ctx_flush(&exec_ctx); |
||||
} |
||||
grpc_exec_ctx_flush(&exec_ctx); |
||||
|
||||
grpc_shutdown(); |
||||
if (leak_check) { |
||||
counters = grpc_memory_counters_snapshot(); |
||||
grpc_memory_counters_destroy(); |
||||
GPR_ASSERT(counters.total_size_relative == 0); |
||||
} |
||||
return 0; |
||||
} |
@ -0,0 +1,44 @@ |
||||
#!/bin/bash |
||||
# Copyright 2016, Google Inc. |
||||
# All rights reserved. |
||||
# |
||||
# Redistribution and use in source and binary forms, with or without |
||||
# modification, are permitted provided that the following conditions are |
||||
# met: |
||||
# |
||||
# * Redistributions of source code must retain the above copyright |
||||
# notice, this list of conditions and the following disclaimer. |
||||
# * Redistributions in binary form must reproduce the above |
||||
# copyright notice, this list of conditions and the following disclaimer |
||||
# in the documentation and/or other materials provided with the |
||||
# distribution. |
||||
# * Neither the name of Google Inc. nor the names of its |
||||
# contributors may be used to endorse or promote products derived from |
||||
# this software without specific prior written permission. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
# |
||||
|
||||
flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=2048 -timeout=120" |
||||
|
||||
if [ "$jobs" != "1" ] |
||||
then |
||||
flags="-jobs=$jobs -workers=$jobs $flags" |
||||
fi |
||||
|
||||
if [ "$config" == "asan-trace-cmp" ] |
||||
then |
||||
flags="-use_traces=1 $flags" |
||||
fi |
||||
|
||||
bins/$config/ssl_server_fuzzer $flags fuzzer_output test/core/security/corpus/ssl_server_corpus |
Loading…
Reference in new issue