Fix a big leak when using stack-allocated BIO items.
[openssl.git] / ssl / bio_ssl.c
index 473b3ff51992fdd8bdef63d3028e66330655bff1..c3afc57f5f2159695b961c93c8f8c4dbf9f0a9f7 100644 (file)
@@ -1,4 +1,3 @@
-/* ssl/bio_ssl.c */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -82,7 +81,7 @@ typedef struct bio_ssl_st {
     unsigned long last_time;
 } BIO_SSL;
 
-static BIO_METHOD methods_sslp = {
+static const BIO_METHOD methods_sslp = {
     BIO_TYPE_SSL, "ssl",
     ssl_write,
     ssl_read,
@@ -94,21 +93,19 @@ static BIO_METHOD methods_sslp = {
     ssl_callback_ctrl,
 };
 
-BIO_METHOD *BIO_f_ssl(void)
+const BIO_METHOD *BIO_f_ssl(void)
 {
     return (&methods_sslp);
 }
 
 static int ssl_new(BIO *bi)
 {
-    BIO_SSL *bs;
+    BIO_SSL *bs = OPENSSL_zalloc(sizeof(*bs));
 
-    bs = (BIO_SSL *)OPENSSL_malloc(sizeof(BIO_SSL));
     if (bs == NULL) {
         BIOerr(BIO_F_SSL_NEW, ERR_R_MALLOC_FAILURE);
         return (0);
     }
-    memset(bs, 0, sizeof(BIO_SSL));
     bi->init = 0;
     bi->ptr = (char *)bs;
     bi->flags = 0;
@@ -130,8 +127,7 @@ static int ssl_free(BIO *a)
         a->init = 0;
         a->flags = 0;
     }
-    if (a->ptr != NULL)
-        OPENSSL_free(a->ptr);
+    OPENSSL_free(a->ptr);
     return (1);
 }
 
@@ -342,7 +338,7 @@ static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
             if (b->next_bio != NULL)
                 BIO_push(bio, b->next_bio);
             b->next_bio = bio;
-            CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO);
+            BIO_up_ref(bio);
         }
         b->init = 1;
         break;
@@ -375,7 +371,7 @@ static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
     case BIO_CTRL_PUSH:
         if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio)) {
             SSL_set_bio(ssl, b->next_bio, b->next_bio);
-            CRYPTO_add(&b->next_bio->references, 1, CRYPTO_LOCK_BIO);
+            BIO_up_ref(b);
         }
         break;
     case BIO_CTRL_POP:
@@ -388,7 +384,7 @@ static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
             if (ssl->rbio != ssl->wbio)
                 BIO_free_all(ssl->wbio);
             if (b->next_bio != NULL)
-                CRYPTO_add(&b->next_bio->references, -1, CRYPTO_LOCK_BIO);
+                BIO_free(b->next_bio);
             ssl->wbio = NULL;
             ssl->rbio = NULL;
         }
@@ -410,6 +406,10 @@ static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
             BIO_set_flags(b, BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY);
             b->retry_reason = b->next_bio->retry_reason;
             break;
+        case SSL_ERROR_WANT_X509_LOOKUP:
+            BIO_set_retry_special(b);
+            b->retry_reason = BIO_RR_SSL_X509_LOOKUP;
+            break;
         default:
             break;
         }