Merge pull request #10630 from ctiller/ubsan

ubsan fixes
diff --git a/src/core/ext/census/context.c b/src/core/ext/census/context.c
index 0dfc4ec..4195cb1 100644
--- a/src/core/ext/census/context.c
+++ b/src/core/ext/census/context.c
@@ -200,7 +200,7 @@
     // allocate new memory if needed
     tags->kvm_size += 2 * CENSUS_MAX_TAG_KV_LEN + TAG_HEADER_SIZE;
     char *new_kvm = gpr_malloc(tags->kvm_size);
-    memcpy(new_kvm, tags->kvm, tags->kvm_used);
+    if (tags->kvm_used > 0) memcpy(new_kvm, tags->kvm, tags->kvm_used);
     gpr_free(tags->kvm);
     tags->kvm = new_kvm;
   }
diff --git a/src/core/ext/census/resource.c b/src/core/ext/census/resource.c
index ed44f00..26ea1a8 100644
--- a/src/core/ext/census/resource.c
+++ b/src/core/ext/census/resource.c
@@ -223,7 +223,9 @@
   if (n_resources == n_defined_resources) {
     size_t new_n_resources = n_resources ? n_resources * 2 : 2;
     resource **new_resources = gpr_malloc(new_n_resources * sizeof(resource *));
-    memcpy(new_resources, resources, n_resources * sizeof(resource *));
+    if (n_resources != 0) {
+      memcpy(new_resources, resources, n_resources * sizeof(resource *));
+    }
     memset(new_resources + n_resources, 0,
            (new_n_resources - n_resources) * sizeof(resource *));
     gpr_free(resources);
diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c
index 4e47c5c..255f538 100644
--- a/src/core/lib/channel/http_client_filter.c
+++ b/src/core/lib/channel/http_client_filter.c
@@ -222,8 +222,10 @@
   while (grpc_byte_stream_next(
       exec_ctx, calld->send_op->payload->send_message.send_message,
       &calld->incoming_slice, ~(size_t)0, &calld->got_slice)) {
-    memcpy(wrptr, GRPC_SLICE_START_PTR(calld->incoming_slice),
-           GRPC_SLICE_LENGTH(calld->incoming_slice));
+    if (GRPC_SLICE_LENGTH(calld->incoming_slice) > 0) {
+      memcpy(wrptr, GRPC_SLICE_START_PTR(calld->incoming_slice),
+             GRPC_SLICE_LENGTH(calld->incoming_slice));
+    }
     wrptr += GRPC_SLICE_LENGTH(calld->incoming_slice);
     grpc_slice_buffer_add(&calld->slices, calld->incoming_slice);
     if (calld->send_length == calld->slices.length) {
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index a0acf5b..0ec5a23 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -967,7 +967,7 @@
           break;
         }
         grpc_op *ops = gpr_malloc(sizeof(grpc_op) * num_ops);
-        memset(ops, 0, sizeof(grpc_op) * num_ops);
+        if (num_ops > 0) memset(ops, 0, sizeof(grpc_op) * num_ops);
         bool ok = true;
         size_t i;
         grpc_op *op;
diff --git a/test/core/support/spinlock_test.c b/test/core/support/spinlock_test.c
index c70e76c..96055e9 100644
--- a/test/core/support/spinlock_test.c
+++ b/test/core/support/spinlock_test.c
@@ -109,7 +109,7 @@
       start, gpr_time_from_micros((int64_t)timeout_s * 1000000, GPR_TIMESPAN));
   fprintf(stderr, "%s:", name);
   while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0) {
-    iterations <<= 1;
+    if (iterations < INT64_MAX / 2) iterations <<= 1;
     fprintf(stderr, " %ld", (long)iterations);
     m = test_new(10, iterations, incr_step);
     test_create_threads(m, body);