Work around more C language bugs with empty spans.

C's specification text around pointer arithmetic is buggy and fails to
account for empty spans. Empty spans are typically represented as
ptr=NULL and len=0, so (T*)NULL + 0 must be defined for ptr + len to
reliably work. C++ does not have this bug and specifies this correctly.
See https://crbug.com/1019588.

This language bug has made its way over to newer versions of UBSan,
which enforce this. In the short term, add bogus length checks as a
workaround. However, unlike the memcpy language bug, we cannot address
this systematically. In the long term, we need to switch libcrypto to
building as C++ for a real fix.

To test this, update our clang revision to that in
https://chromium-review.googlesource.com/c/chromium/src/+/1879890. Note
that clang revision was later reverted in Chromium for seemingly
unrelated reasons.

This newer UBSan also catches a memcpy/OPENSSL_memcpy issue in
siphash.c, from the earlier C NULL bug we'd been working around.

Bug: chromium:1019588, chromium:1019644
Change-Id: I460e547c8cd740db68da8cc2a3a970276ec92e90
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/38584
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
diff --git a/crypto/buf/buf.c b/crypto/buf/buf.c
index 717aaac..bd97dd3 100644
--- a/crypto/buf/buf.c
+++ b/crypto/buf/buf.c
@@ -132,6 +132,10 @@
 }
 
 int BUF_MEM_append(BUF_MEM *buf, const void *in, size_t len) {
+  // Work around a C language bug. See https://crbug.com/1019588.
+  if (len == 0) {
+    return 1;
+  }
   size_t new_len = buf->length + len;
   if (new_len < len) {
     OPENSSL_PUT_ERROR(BUF, ERR_R_OVERFLOW);
diff --git a/crypto/fipsmodule/modes/gcm.c b/crypto/fipsmodule/modes/gcm.c
index ca077ac..3860ebe 100644
--- a/crypto/fipsmodule/modes/gcm.c
+++ b/crypto/fipsmodule/modes/gcm.c
@@ -699,7 +699,8 @@
   }
 
 #if defined(AESNI_GCM)
-  if (ctx->gcm_key.use_aesni_gcm_crypt) {
+  // Check |len| to work around a C language bug. See https://crbug.com/1019588.
+  if (ctx->gcm_key.use_aesni_gcm_crypt && len > 0) {
     // |aesni_gcm_encrypt| may not process all the input given to it. It may
     // not process *any* of its input if it is deemed too small.
     size_t bulk = aesni_gcm_encrypt(in, out, len, key, ctx->Yi.c, ctx->Xi.u);
@@ -786,7 +787,8 @@
   }
 
 #if defined(AESNI_GCM)
-  if (ctx->gcm_key.use_aesni_gcm_crypt) {
+  // Check |len| to work around a C language bug. See https://crbug.com/1019588.
+  if (ctx->gcm_key.use_aesni_gcm_crypt && len > 0) {
     // |aesni_gcm_decrypt| may not process all the input given to it. It may
     // not process *any* of its input if it is deemed too small.
     size_t bulk = aesni_gcm_decrypt(in, out, len, key, ctx->Yi.c, ctx->Xi.u);
diff --git a/crypto/poly1305/poly1305_vec.c b/crypto/poly1305/poly1305_vec.c
index 480d9e5..e7b3ae5 100644
--- a/crypto/poly1305/poly1305_vec.c
+++ b/crypto/poly1305/poly1305_vec.c
@@ -662,6 +662,11 @@
   poly1305_state_internal *st = poly1305_aligned_state(state);
   size_t want;
 
+  // Work around a C language bug. See https://crbug.com/1019588.
+  if (bytes == 0) {
+    return;
+  }
+
   // need at least 32 initial bytes to start the accelerated branch
   if (!st->started) {
     if ((st->leftover == 0) && (bytes > 32)) {
diff --git a/crypto/siphash/siphash.c b/crypto/siphash/siphash.c
index 7e4e9c5..f55c3ca 100644
--- a/crypto/siphash/siphash.c
+++ b/crypto/siphash/siphash.c
@@ -17,6 +17,8 @@
 
 #include <openssl/siphash.h>
 
+#include "../internal.h"
+
 
 static void siphash_round(uint64_t v[4]) {
   v[0] += v[1];
@@ -62,7 +64,7 @@
     uint64_t word;
   } last_block;
   last_block.word = 0;
-  memcpy(last_block.bytes, input, input_len);
+  OPENSSL_memcpy(last_block.bytes, input, input_len);
   last_block.bytes[7] = orig_input_len & 0xff;
 
   v[3] ^= last_block.word;
diff --git a/util/bot/update_clang.py b/util/bot/update_clang.py
index c36ec66..1ed40dc 100644
--- a/util/bot/update_clang.py
+++ b/util/bot/update_clang.py
@@ -19,8 +19,8 @@
 # CLANG_REVISION and CLANG_SUB_REVISION determine the build of clang
 # to use. These should be synced with tools/clang/scripts/update.py in
 # Chromium.
-CLANG_REVISION = '8455294f2ac13d587b13d728038a9bffa7185f2b'
-CLANG_SVN_REVISION = '371202'
+CLANG_REVISION = '55c223a7ed522293cf9995d07d348368c345d1f2'
+CLANG_SVN_REVISION = 'n330255'
 CLANG_SUB_REVISION = 1
 
 PACKAGE_VERSION = '%s-%s-%s' % (CLANG_SVN_REVISION, CLANG_REVISION[:8],