Add OPENSSL_asprintf and friends for asprintf(3) functionality.

This includes an internal version which allows a flag to specify
the use of system malloc, or OPENSSL_malloc - this in turn allows
us to use this function in the ERR family of functions and allow
for ERR to not call OPENSSL_malloc with a circular dependency.

Bug: 564

Change-Id: Ifd02d062fda9695cddbb0dbef2e1c1db0802a486
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/57005
Auto-Submit: Bob Beck <bbe@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
diff --git a/crypto/internal.h b/crypto/internal.h
index 576ad85..f12871f 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -1299,6 +1299,13 @@
 extern uint8_t BORINGSSL_function_hit[7];
 #endif  // BORINGSSL_DISPATCH_TEST
 
+// OPENSSL_vasprintf_internal is just like |vasprintf(3)|. if |system_malloc| is
+// 0, memory will be allocated with |OPENSSL_malloc| and must be freed with
+// |OPENSSL_free|. Otherwise the system |malloc| function is used and the memory
+// must be freed with the system |free| function.
+OPENSSL_EXPORT int OPENSSL_vasprintf_internal(char **str, const char *format,
+                                              va_list args, int system_malloc)
+    OPENSSL_PRINTF_FORMAT_FUNC(2, 0);
 
 #if defined(__cplusplus)
 }  // extern C
diff --git a/crypto/mem.c b/crypto/mem.c
index 97a85e9..f75e89e 100644
--- a/crypto/mem.c
+++ b/crypto/mem.c
@@ -57,9 +57,11 @@
 #include <openssl/mem.h>
 
 #include <assert.h>
+#include <errno.h>
+#include <limits.h>
 #include <stdarg.h>
-#include <stdlib.h>
 #include <stdio.h>
+#include <stdlib.h>
 
 #include <openssl/err.h>
 
@@ -127,7 +129,7 @@
 // primitives used must tolerate every other synchronization primitive linked
 // into the process, including pthreads locks. Failing to meet these constraints
 // may result in deadlocks, crashes, or memory corruption.
-WEAK_SYMBOL_FUNC(void*, OPENSSL_memory_alloc, (size_t size));
+WEAK_SYMBOL_FUNC(void *, OPENSSL_memory_alloc, (size_t size));
 WEAK_SYMBOL_FUNC(void, OPENSSL_memory_free, (void *ptr));
 WEAK_SYMBOL_FUNC(size_t, OPENSSL_memory_get_size, (void *ptr));
 
@@ -135,10 +137,25 @@
 // are linking in BoringSSL and, roughly, what version they are using.
 static const uint8_t kBoringSSLBinaryTag[18] = {
     // 16 bytes of magic tag.
-    0x8c, 0x62, 0x20, 0x0b, 0xd2, 0xa0, 0x72, 0x58,
-    0x44, 0xa8, 0x96, 0x69, 0xad, 0x55, 0x7e, 0xec,
+    0x8c,
+    0x62,
+    0x20,
+    0x0b,
+    0xd2,
+    0xa0,
+    0x72,
+    0x58,
+    0x44,
+    0xa8,
+    0x96,
+    0x69,
+    0xad,
+    0x55,
+    0x7e,
+    0xec,
     // Current source iteration. Incremented ~monthly.
-    3, 0,
+    3,
+    0,
 };
 
 #if defined(BORINGSSL_MALLOC_FAILURE_TESTING)
@@ -321,9 +338,7 @@
 #endif  // !OPENSSL_NO_ASM
 }
 
-void OPENSSL_clear_free(void *ptr, size_t unused) {
-  OPENSSL_free(ptr);
-}
+void OPENSSL_clear_free(void *ptr, size_t unused) { OPENSSL_free(ptr); }
 
 int CRYPTO_secure_malloc_init(size_t size, size_t min_size) { return 0; }
 
@@ -394,9 +409,7 @@
   return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
 }
 
-int OPENSSL_isdigit(int c) {
-  return c >= '0' && c <= '9';
-}
+int OPENSSL_isdigit(int c) { return c >= '0' && c <= '9'; }
 
 int OPENSSL_isxdigit(int c) {
   return OPENSSL_isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
@@ -418,9 +431,7 @@
   return 0;
 }
 
-int OPENSSL_isalnum(int c) {
-  return OPENSSL_isalpha(c) || OPENSSL_isdigit(c);
-}
+int OPENSSL_isalnum(int c) { return OPENSSL_isalpha(c) || OPENSSL_isdigit(c); }
 
 int OPENSSL_tolower(int c) {
   if (c >= 'A' && c <= 'Z') {
@@ -478,6 +489,65 @@
   return vsnprintf(buf, n, format, args);
 }
 
+int OPENSSL_vasprintf_internal(char **str, const char *format, va_list args,
+                               int system_malloc) {
+  void *(*allocate)(size_t) = system_malloc ? malloc : OPENSSL_malloc;
+  void (*deallocate)(void *) = system_malloc ? free : OPENSSL_free;
+  void *(*reallocate)(void *, size_t) =
+      system_malloc ? realloc : OPENSSL_realloc;
+  char *candidate = NULL;
+  size_t candidate_len = 64;  // TODO(bbe) what's the best initial size?
+
+  if ((candidate = allocate(candidate_len)) == NULL) {
+    goto err;
+  }
+  va_list args_copy;
+  va_copy(args_copy, args);
+  int ret = vsnprintf(candidate, candidate_len, format, args_copy);
+  va_end(args_copy);
+  if (ret == INT_MAX || ret < 0) {
+    // Failed, or size not int representable.
+    goto err;
+  }
+  if ((size_t)ret >= candidate_len) {
+    // Too big to fit in allocation.
+    char *tmp;
+
+    candidate_len = ret + 1;
+    if ((tmp = reallocate(candidate, candidate_len)) == NULL) {
+      goto err;
+    }
+    candidate = tmp;
+    va_copy(args_copy, args);
+    ret = vsnprintf(candidate, candidate_len, format, args_copy);
+    va_end(args_copy);
+  }
+  // At this point this can't happen unless vsnprintf is insane.
+  if (ret < 0 || (size_t)ret >= candidate_len) {
+    goto err;
+  }
+  *str = candidate;
+  return ret;
+
+ err:
+  deallocate(candidate);
+  *str = NULL;
+  errno = ENOMEM;
+  return -1;
+}
+
+int OPENSSL_vasprintf(char **str, const char *format, va_list args) {
+  return OPENSSL_vasprintf_internal(str, format, args, /*system_malloc=*/0);
+}
+
+int OPENSSL_asprintf(char **str, const char *format, ...) {
+  va_list args;
+  va_start(args, format);
+  int ret = OPENSSL_vasprintf(str, format, args);
+  va_end(args);
+  return ret;
+}
+
 char *OPENSSL_strndup(const char *str, size_t size) {
   size = OPENSSL_strnlen(str, size);
 
diff --git a/include/openssl/mem.h b/include/openssl/mem.h
index 374e188..0cce93d 100644
--- a/include/openssl/mem.h
+++ b/include/openssl/mem.h
@@ -84,7 +84,8 @@
 
 // OPENSSL_realloc returns a pointer to a buffer of |new_size| bytes that
 // contains the contents of |ptr|. Unlike |realloc|, a new buffer is always
-// allocated and the data at |ptr| is always wiped and freed.
+// allocated and the data at |ptr| is always wiped and freed. Memory is
+// allocated with |OPENSSL_malloc| and must be freed with |OPENSSL_free|.
 OPENSSL_EXPORT void *OPENSSL_realloc(void *ptr, size_t new_size);
 
 // OPENSSL_cleanse zeros out |len| bytes of memory at |ptr|. This is similar to
@@ -160,12 +161,25 @@
 OPENSSL_EXPORT int BIO_vsnprintf(char *buf, size_t n, const char *format,
                                  va_list args) OPENSSL_PRINTF_FORMAT_FUNC(3, 0);
 
+// OPENSSL_vasprintf has the same behavior as vasprintf(3), except that
+// memory allocated in a returned string must be freed with |OPENSSL_free|.
+OPENSSL_EXPORT int OPENSSL_vasprintf(char **str, const char *format,
+                                     va_list args)
+    OPENSSL_PRINTF_FORMAT_FUNC(2, 0);
+
+// OPENSSL_asprintf has the same behavior as asprintf(3), except that
+// memory allocated in a returned string must be freed with |OPENSSL_free|.
+OPENSSL_EXPORT int OPENSSL_asprintf(char **str, const char *format, ...)
+    OPENSSL_PRINTF_FORMAT_FUNC(2, 3);
+
 // OPENSSL_strndup returns an allocated, duplicate of |str|, which is, at most,
-// |size| bytes. The result is always NUL terminated.
+// |size| bytes. The result is always NUL terminated. The memory allocated
+// must be freed with |OPENSSL_free|.
 OPENSSL_EXPORT char *OPENSSL_strndup(const char *str, size_t size);
 
 // OPENSSL_memdup returns an allocated, duplicate of |size| bytes from |data| or
-// NULL on allocation failure.
+// NULL on allocation failure. The memory allocated must be freed with
+// |OPENSSL_free|.
 OPENSSL_EXPORT void *OPENSSL_memdup(const void *data, size_t size);
 
 // OPENSSL_strlcpy acts like strlcpy(3).