diff --git a/build.yaml b/build.yaml index 09ab5276f9104d49e5008536dd4baa790b0e0c66..659c861977374d37f64f079346b294cc7c3276d3 100644 --- a/build.yaml +++ b/build.yaml @@ -3295,7 +3295,7 @@ configs: LDXX: clang++ compile_the_world: true test_environ: - UBSAN_OPTIONS: print_stacktrace=1 + UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1 timeout_multiplier: 1.5 defaults: boringssl: diff --git a/src/core/ext/client_config/subchannel.c b/src/core/ext/client_config/subchannel.c index bd45d3825cc5527c84ac923809b05541ee90fd84..cfd39e7cfbfefab1624ab230d1c32c3a08161675 100644 --- a/src/core/ext/client_config/subchannel.c +++ b/src/core/ext/client_config/subchannel.c @@ -320,7 +320,7 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx, c->filters = NULL; } c->addr = gpr_malloc(args->addr_len); - memcpy(c->addr, args->addr, args->addr_len); + if (args->addr_len) memcpy(c->addr, args->addr, args->addr_len); c->pollset_set = grpc_pollset_set_create(); c->addr_len = args->addr_len; grpc_set_initial_connect_string(&c->addr, &c->addr_len, diff --git a/src/core/ext/client_config/subchannel_index.c b/src/core/ext/client_config/subchannel_index.c index ab8d9bd91d83ab23cc952512d91feaaac6e8715a..690cb16b96f06237017603ce49ff503cde43fb76 100644 --- a/src/core/ext/client_config/subchannel_index.c +++ b/src/core/ext/client_config/subchannel_index.c @@ -77,12 +77,19 @@ static grpc_subchannel_key *create_key( grpc_subchannel_key *k = gpr_malloc(sizeof(*k)); k->connector = grpc_connector_ref(connector); k->args.filter_count = args->filter_count; - k->args.filters = gpr_malloc(sizeof(*k->args.filters) * k->args.filter_count); - memcpy((grpc_channel_filter *)k->args.filters, args->filters, - sizeof(*k->args.filters) * k->args.filter_count); + if (k->args.filter_count > 0) { + k->args.filters = + gpr_malloc(sizeof(*k->args.filters) * k->args.filter_count); + memcpy((grpc_channel_filter *)k->args.filters, args->filters, + sizeof(*k->args.filters) * k->args.filter_count); + } else { + k->args.filters = NULL; + } k->args.addr_len = args->addr_len; k->args.addr = gpr_malloc(args->addr_len); - memcpy(k->args.addr, args->addr, k->args.addr_len); + if (k->args.addr_len > 0) { + memcpy(k->args.addr, args->addr, k->args.addr_len); + } k->args.args = copy_channel_args(args->args); return k; } @@ -104,11 +111,15 @@ static int subchannel_key_compare(grpc_subchannel_key *a, if (c != 0) return c; c = GPR_ICMP(a->args.filter_count, b->args.filter_count); if (c != 0) return c; - c = memcmp(a->args.addr, b->args.addr, a->args.addr_len); - if (c != 0) return c; - c = memcmp(a->args.filters, b->args.filters, - a->args.filter_count * sizeof(*a->args.filters)); - if (c != 0) return c; + if (a->args.addr_len) { + c = memcmp(a->args.addr, b->args.addr, a->args.addr_len); + if (c != 0) return c; + } + if (a->args.filter_count > 0) { + c = memcmp(a->args.filters, b->args.filters, + a->args.filter_count * sizeof(*a->args.filters)); + if (c != 0) return c; + } return grpc_channel_args_compare(a->args.args, b->args.args); } diff --git a/src/core/ext/transport/chttp2/transport/frame_goaway.c b/src/core/ext/transport/chttp2/transport/frame_goaway.c index 69accb7696dd8ad93a982b379446d2b35a830974..827e7a697707f9b44d6c4d972cd6c39f3b7247f6 100644 --- a/src/core/ext/transport/chttp2/transport/frame_goaway.c +++ b/src/core/ext/transport/chttp2/transport/frame_goaway.c @@ -137,7 +137,8 @@ grpc_chttp2_parse_error grpc_chttp2_goaway_parser_parse( ++cur; /* fallthrough */ case GRPC_CHTTP2_GOAWAY_DEBUG: - memcpy(p->debug_data + p->debug_pos, cur, (size_t)(end - cur)); + if (end != cur) + memcpy(p->debug_data + p->debug_pos, cur, (size_t)(end - cur)); GPR_ASSERT((size_t)(end - cur) < UINT32_MAX - p->debug_pos); p->debug_pos += (uint32_t)(end - cur); p->state = GRPC_CHTTP2_GOAWAY_DEBUG; diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.c b/src/core/ext/transport/chttp2/transport/hpack_parser.c index 687936bfd35a51f96d4749e12d3a1f6363205e69..ed45bc9cb38a9ab297ebaf774aee5fa52615bf9f 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_parser.c +++ b/src/core/ext/transport/chttp2/transport/hpack_parser.c @@ -1138,6 +1138,7 @@ static int parse_string_prefix(grpc_chttp2_hpack_parser *p, const uint8_t *cur, /* append some bytes to a string */ static void append_bytes(grpc_chttp2_hpack_parser_string *str, const uint8_t *data, size_t length) { + if (length == 0) return; if (length + str->length > str->capacity) { GPR_ASSERT(str->length + length <= UINT32_MAX); str->capacity = (uint32_t)(str->length + length); @@ -1445,6 +1446,11 @@ grpc_chttp2_parse_error grpc_chttp2_header_parser_parse( stream id on a header */ if (stream_parsing != NULL) { if (parser->is_boundary) { + if (stream_parsing->header_frames_received == + GPR_ARRAY_SIZE(stream_parsing->got_metadata_on_parse)) { + gpr_log(GPR_ERROR, "too many trailer frames"); + return GRPC_CHTTP2_CONNECTION_ERROR; + } stream_parsing ->got_metadata_on_parse[stream_parsing->header_frames_received] = 1; stream_parsing->header_frames_received++; diff --git a/src/core/lib/channel/channel_args.c b/src/core/lib/channel/channel_args.c index 893cf0700e54ad39c6de8af8c852d94c61781061..569be4dc2825113b1119ce1f8b66116d1a9710a2 100644 --- a/src/core/lib/channel/channel_args.c +++ b/src/core/lib/channel/channel_args.c @@ -132,7 +132,8 @@ grpc_channel_args *grpc_channel_args_normalize(const grpc_channel_args *a) { for (size_t i = 0; i < a->num_args; i++) { args[i] = &a->args[i]; } - qsort(args, a->num_args, sizeof(grpc_arg *), cmp_key_stable); + if (a->num_args > 1) + qsort(args, a->num_args, sizeof(grpc_arg *), cmp_key_stable); grpc_channel_args *b = gpr_malloc(sizeof(grpc_channel_args)); b->num_args = a->num_args; diff --git a/src/core/lib/compression/compression_algorithm.c b/src/core/lib/compression/compression_algorithm.c index 7039364b7bcbb5b2c0896802b047aa6d6b1eee41..820871d579bf590f3691e0bb4c9729fcfd54fa64 100644 --- a/src/core/lib/compression/compression_algorithm.c +++ b/src/core/lib/compression/compression_algorithm.c @@ -199,5 +199,6 @@ void grpc_compression_options_disable_algorithm( int grpc_compression_options_is_algorithm_enabled( const grpc_compression_options *opts, grpc_compression_algorithm algorithm) { + if (algorithm >= GRPC_COMPRESS_ALGORITHMS_COUNT) return 0; return GPR_BITGET(opts->enabled_algorithms_bitset, algorithm); } diff --git a/src/core/lib/support/murmur_hash.c b/src/core/lib/support/murmur_hash.c index 5711fff0c0fc207257c00bf60af51f1c2d4c1be1..7137c1f31332c3ea2eff64840be341849c2a6b29 100644 --- a/src/core/lib/support/murmur_hash.c +++ b/src/core/lib/support/murmur_hash.c @@ -33,6 +33,8 @@ #include "src/core/lib/support/murmur_hash.h" +#include <string.h> + #define ROTL32(x, r) ((x) << (r)) | ((x) >> (32 - (r))) #define FMIX32(h) \ @@ -42,10 +44,6 @@ (h) *= 0xc2b2ae35; \ (h) ^= (h) >> 16; -/* Block read - if your platform needs to do endian-swapping or can only - handle aligned reads, do the conversion here */ -#define GETBLOCK32(p, i) (p)[(i)] - uint32_t gpr_murmur_hash3(const void *key, size_t len, uint32_t seed) { const uint8_t *data = (const uint8_t *)key; const size_t nblocks = len / 4; @@ -62,7 +60,7 @@ uint32_t gpr_murmur_hash3(const void *key, size_t len, uint32_t seed) { /* body */ for (i = -(int)nblocks; i; i++) { - k1 = GETBLOCK32(blocks, i); + memcpy(&k1, blocks + i, sizeof(uint32_t)); k1 *= c1; k1 = ROTL32(k1, 15); diff --git a/src/core/lib/transport/metadata.c b/src/core/lib/transport/metadata.c index 5847ec9053d6a24fbf801a1f420703f6b7de6e56..82c8e239f6870c53bbee2dc5792c2d4cd5b52d40 100644 --- a/src/core/lib/transport/metadata.c +++ b/src/core/lib/transport/metadata.c @@ -373,7 +373,8 @@ grpc_mdstr *grpc_mdstr_from_buffer(const uint8_t *buf, size_t length) { ss = g_static_strtab[idx]; if (ss == NULL) break; if (ss->hash == hash && GPR_SLICE_LENGTH(ss->slice) == length && - 0 == memcmp(buf, GPR_SLICE_START_PTR(ss->slice), length)) { + (length == 0 || + 0 == memcmp(buf, GPR_SLICE_START_PTR(ss->slice), length))) { GPR_TIMER_END("grpc_mdstr_from_buffer", 0); return ss; } diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c index cdfa9606236ee58b75f1813edba78a7762076d8a..a8b123257fdc16b0ee90fbf77370cad763193e56 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.c +++ b/test/core/end2end/fuzzers/api_fuzzer.c @@ -424,15 +424,19 @@ static void add_to_free(call_state *call, void *p) { static void read_metadata(input_stream *inp, size_t *count, grpc_metadata **metadata, call_state *cs) { *count = next_byte(inp); - *metadata = gpr_malloc(*count * sizeof(**metadata)); - memset(*metadata, 0, *count * sizeof(**metadata)); - for (size_t i = 0; i < *count; i++) { - (*metadata)[i].key = read_string(inp); - read_buffer(inp, (char **)&(*metadata)[i].value, - &(*metadata)[i].value_length); - (*metadata)[i].flags = read_uint32(inp); - add_to_free(cs, (void *)(*metadata)[i].key); - add_to_free(cs, (void *)(*metadata)[i].value); + if (*count) { + *metadata = gpr_malloc(*count * sizeof(**metadata)); + memset(*metadata, 0, *count * sizeof(**metadata)); + for (size_t i = 0; i < *count; i++) { + (*metadata)[i].key = read_string(inp); + read_buffer(inp, (char **)&(*metadata)[i].value, + &(*metadata)[i].value_length); + (*metadata)[i].flags = read_uint32(inp); + add_to_free(cs, (void *)(*metadata)[i].key); + add_to_free(cs, (void *)(*metadata)[i].value); + } + } else { + *metadata = gpr_malloc(1); } add_to_free(cs, *metadata); } diff --git a/tools/run_tests/configs.json b/tools/run_tests/configs.json index bcc4118d2f3a64c553c8414b8e6923b04b10af89..b0839ef026a5af61412b050d94aa568e6680eb48 100644 --- a/tools/run_tests/configs.json +++ b/tools/run_tests/configs.json @@ -57,7 +57,7 @@ { "config": "ubsan", "environ": { - "UBSAN_OPTIONS": "print_stacktrace=1" + "UBSAN_OPTIONS": "halt_on_error=1:print_stacktrace=1" }, "timeout_multiplier": 1.5 },