Fix memory leak on sk_X509_EXTENSION_push failure.

(Imported from upstream's c29f83c05f3a3c5641c5ddf054789a29d2163bf3.)

ext was being leaked. Upstream also did some stuff around *x which
wasn't strictly necessary (usually OpenSSL only provides basic
exception safety, not strong exception safety), but ah well.

Change-Id: I52d230990b05501b4cee6deee8dcacba4a926c18
Reviewed-on: https://boringssl-review.googlesource.com/23204
Reviewed-by: Steven Valdez <svaldez@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/x509v3/v3_lib.c b/crypto/x509v3/v3_lib.c
index c4718e3..8f5435d 100644
--- a/crypto/x509v3/v3_lib.c
+++ b/crypto/x509v3/v3_lib.c
@@ -288,9 +288,9 @@
 int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
                     int crit, unsigned long flags)
 {
-    int extidx = -1;
-    int errcode;
-    X509_EXTENSION *ext, *extmp;
+    int errcode, extidx = -1;
+    X509_EXTENSION *ext = NULL, *extmp;
+    STACK_OF(X509_EXTENSION) *ret = NULL;
     unsigned long ext_op = flags & X509V3_ADD_OP_MASK;
 
     /*
@@ -348,13 +348,21 @@
         return 1;
     }
 
-    if (!*x && !(*x = sk_X509_EXTENSION_new_null()))
-        return -1;
-    if (!sk_X509_EXTENSION_push(*x, ext))
-        return -1;
+    if ((ret = *x) == NULL
+         && (ret = sk_X509_EXTENSION_new_null()) == NULL)
+        goto m_fail;
+    if (!sk_X509_EXTENSION_push(ret, ext))
+        goto m_fail;
 
+    *x = ret;
     return 1;
 
+ m_fail:
+    if (ret != *x)
+        sk_X509_EXTENSION_free(ret);
+    X509_EXTENSION_free(ext);
+    return -1;
+
  err:
     if (!(flags & X509V3_ADD_SILENT))
         OPENSSL_PUT_ERROR(X509V3, errcode);