Home | History | Annotate | Line # | Download | only in test
bio_memleak_test.c revision 1.1.1.1
      1 /*
      2  * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 #include <stdio.h>
     10 #include <string.h>
     11 #include <openssl/buffer.h>
     12 #include <openssl/bio.h>
     13 
     14 #include "testutil.h"
     15 
     16 static int test_bio_memleak(void)
     17 {
     18     int ok = 0;
     19     BIO *bio;
     20     BUF_MEM bufmem;
     21     static const char str[] = "BIO test\n";
     22     char buf[100];
     23 
     24     bio = BIO_new(BIO_s_mem());
     25     if (!TEST_ptr(bio))
     26         goto finish;
     27     bufmem.length = sizeof(str);
     28     bufmem.data = (char *) str;
     29     bufmem.max = bufmem.length;
     30     BIO_set_mem_buf(bio, &bufmem, BIO_NOCLOSE);
     31     BIO_set_flags(bio, BIO_FLAGS_MEM_RDONLY);
     32     if (!TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(str)))
     33         goto finish;
     34     if (!TEST_mem_eq(buf, sizeof(str), str, sizeof(str)))
     35         goto finish;
     36     ok = 1;
     37 
     38  finish:
     39     BIO_free(bio);
     40     return ok;
     41 }
     42 
     43 static int test_bio_get_mem(void)
     44 {
     45     int ok = 0;
     46     BIO *bio = NULL;
     47     BUF_MEM *bufmem = NULL;
     48 
     49     bio = BIO_new(BIO_s_mem());
     50     if (!TEST_ptr(bio))
     51         goto finish;
     52     if (!TEST_int_eq(BIO_puts(bio, "Hello World\n"), 12))
     53         goto finish;
     54     BIO_get_mem_ptr(bio, &bufmem);
     55     if (!TEST_ptr(bufmem))
     56         goto finish;
     57     if (!TEST_int_gt(BIO_set_close(bio, BIO_NOCLOSE), 0))
     58         goto finish;
     59     BIO_free(bio);
     60     bio = NULL;
     61     if (!TEST_mem_eq(bufmem->data, bufmem->length, "Hello World\n", 12))
     62         goto finish;
     63     ok = 1;
     64 
     65  finish:
     66     BIO_free(bio);
     67     BUF_MEM_free(bufmem);
     68     return ok;
     69 }
     70 
     71 static int test_bio_new_mem_buf(void)
     72 {
     73     int ok = 0;
     74     BIO *bio;
     75     BUF_MEM *bufmem;
     76     char data[16];
     77 
     78     bio = BIO_new_mem_buf("Hello World\n", 12);
     79     if (!TEST_ptr(bio))
     80         goto finish;
     81     if (!TEST_int_eq(BIO_read(bio, data, 5), 5))
     82         goto finish;
     83     if (!TEST_mem_eq(data, 5, "Hello", 5))
     84         goto finish;
     85     if (!TEST_int_gt(BIO_get_mem_ptr(bio, &bufmem), 0))
     86         goto finish;
     87     if (!TEST_int_lt(BIO_write(bio, "test", 4), 0))
     88         goto finish;
     89     if (!TEST_int_eq(BIO_read(bio, data, 16), 7))
     90         goto finish;
     91     if (!TEST_mem_eq(data, 7, " World\n", 7))
     92         goto finish;
     93     if (!TEST_int_gt(BIO_reset(bio), 0))
     94         goto finish;
     95     if (!TEST_int_eq(BIO_read(bio, data, 16), 12))
     96         goto finish;
     97     if (!TEST_mem_eq(data, 12, "Hello World\n", 12))
     98         goto finish;
     99     ok = 1;
    100 
    101  finish:
    102     BIO_free(bio);
    103     return ok;
    104 }
    105 
    106 static int test_bio_rdonly_mem_buf(void)
    107 {
    108     int ok = 0;
    109     BIO *bio, *bio2 = NULL;
    110     BUF_MEM *bufmem;
    111     char data[16];
    112 
    113     bio = BIO_new_mem_buf("Hello World\n", 12);
    114     if (!TEST_ptr(bio))
    115         goto finish;
    116     if (!TEST_int_eq(BIO_read(bio, data, 5), 5))
    117         goto finish;
    118     if (!TEST_mem_eq(data, 5, "Hello", 5))
    119         goto finish;
    120     if (!TEST_int_gt(BIO_get_mem_ptr(bio, &bufmem), 0))
    121         goto finish;
    122     (void)BIO_set_close(bio, BIO_NOCLOSE);
    123 
    124     bio2 = BIO_new(BIO_s_mem());
    125     if (!TEST_ptr(bio2))
    126         goto finish;
    127     BIO_set_mem_buf(bio2, bufmem, BIO_CLOSE);
    128     BIO_set_flags(bio2, BIO_FLAGS_MEM_RDONLY);
    129 
    130     if (!TEST_int_eq(BIO_read(bio2, data, 16), 7))
    131         goto finish;
    132     if (!TEST_mem_eq(data, 7, " World\n", 7))
    133         goto finish;
    134     if (!TEST_int_gt(BIO_reset(bio2), 0))
    135         goto finish;
    136     if (!TEST_int_eq(BIO_read(bio2, data, 16), 7))
    137         goto finish;
    138     if (!TEST_mem_eq(data, 7, " World\n", 7))
    139         goto finish;
    140     ok = 1;
    141 
    142  finish:
    143     BIO_free(bio);
    144     BIO_free(bio2);
    145     return ok;
    146 }
    147 
    148 static int test_bio_rdwr_rdonly(void)
    149 {
    150     int ok = 0;
    151     BIO *bio = NULL;
    152     char data[16];
    153 
    154     bio = BIO_new(BIO_s_mem());
    155     if (!TEST_ptr(bio))
    156         goto finish;
    157     if (!TEST_int_eq(BIO_puts(bio, "Hello World\n"), 12))
    158         goto finish;
    159 
    160     BIO_set_flags(bio, BIO_FLAGS_MEM_RDONLY);
    161     if (!TEST_int_eq(BIO_read(bio, data, 16), 12))
    162         goto finish;
    163     if (!TEST_mem_eq(data, 12, "Hello World\n", 12))
    164         goto finish;
    165     if (!TEST_int_gt(BIO_reset(bio), 0))
    166         goto finish;
    167 
    168     BIO_clear_flags(bio, BIO_FLAGS_MEM_RDONLY);
    169     if (!TEST_int_eq(BIO_puts(bio, "Hi!\n"), 4))
    170         goto finish;
    171     if (!TEST_int_eq(BIO_read(bio, data, 16), 16))
    172         goto finish;
    173 
    174     if (!TEST_mem_eq(data, 16, "Hello World\nHi!\n", 16))
    175         goto finish;
    176 
    177     ok = 1;
    178 
    179  finish:
    180     BIO_free(bio);
    181     return ok;
    182 }
    183 
    184 static int test_bio_nonclear_rst(void)
    185 {
    186     int ok = 0;
    187     BIO *bio = NULL;
    188     char data[16];
    189 
    190     bio = BIO_new(BIO_s_mem());
    191     if (!TEST_ptr(bio))
    192         goto finish;
    193     if (!TEST_int_eq(BIO_puts(bio, "Hello World\n"), 12))
    194         goto finish;
    195 
    196     BIO_set_flags(bio, BIO_FLAGS_NONCLEAR_RST);
    197 
    198     if (!TEST_int_eq(BIO_read(bio, data, 16), 12))
    199         goto finish;
    200     if (!TEST_mem_eq(data, 12, "Hello World\n", 12))
    201         goto finish;
    202     if (!TEST_int_gt(BIO_reset(bio), 0))
    203         goto finish;
    204 
    205     if (!TEST_int_eq(BIO_read(bio, data, 16), 12))
    206         goto finish;
    207     if (!TEST_mem_eq(data, 12, "Hello World\n", 12))
    208         goto finish;
    209 
    210     BIO_clear_flags(bio, BIO_FLAGS_NONCLEAR_RST);
    211     if (!TEST_int_gt(BIO_reset(bio), 0))
    212         goto finish;
    213 
    214     if (!TEST_int_lt(BIO_read(bio, data, 16), 1))
    215         goto finish;
    216 
    217     ok = 1;
    218 
    219  finish:
    220     BIO_free(bio);
    221     return ok;
    222 }
    223 
    224 static int error_callback_fired;
    225 static long BIO_error_callback(BIO *bio, int cmd, const char *argp,
    226                                size_t len, int argi,
    227                                long argl, int ret, size_t *processed)
    228 {
    229     if ((cmd & (BIO_CB_READ | BIO_CB_RETURN)) != 0) {
    230         error_callback_fired = 1;
    231         ret = 0;  /* fail for read operations to simulate error in input BIO */
    232     }
    233     return ret;
    234 }
    235 
    236 /* Checks i2d_ASN1_bio_stream() is freeing all memory when input BIO ends unexpectedly. */
    237 static int test_bio_i2d_ASN1_mime(void)
    238 {
    239     int ok = 0;
    240     BIO *bio = NULL, *out = NULL;
    241     BUF_MEM bufmem;
    242     static const char str[] = "BIO mime test\n";
    243     PKCS7 *p7 = NULL;
    244 
    245     if (!TEST_ptr(bio = BIO_new(BIO_s_mem())))
    246         goto finish;
    247 
    248     bufmem.length = sizeof(str);
    249     bufmem.data = (char *) str;
    250     bufmem.max = bufmem.length;
    251     BIO_set_mem_buf(bio, &bufmem, BIO_NOCLOSE);
    252     BIO_set_flags(bio, BIO_FLAGS_MEM_RDONLY);
    253     BIO_set_callback_ex(bio, BIO_error_callback);
    254 
    255     if (!TEST_ptr(out = BIO_new(BIO_s_mem())))
    256         goto finish;
    257     if (!TEST_ptr(p7 = PKCS7_new()))
    258         goto finish;
    259     if (!TEST_true(PKCS7_set_type(p7, NID_pkcs7_data)))
    260         goto finish;
    261 
    262     error_callback_fired = 0;
    263 
    264     if (!TEST_false(i2d_ASN1_bio_stream(out, (ASN1_VALUE*) p7, bio,
    265                                         SMIME_STREAM | SMIME_BINARY,
    266                                         ASN1_ITEM_rptr(PKCS7))))
    267         goto finish;
    268 
    269     if (!TEST_int_eq(error_callback_fired, 1))
    270         goto finish;
    271 
    272     ok = 1;
    273 
    274  finish:
    275     BIO_free(bio);
    276     BIO_free(out);
    277     PKCS7_free(p7);
    278     return ok;
    279 }
    280 
    281 int setup_tests(void)
    282 {
    283     ADD_TEST(test_bio_memleak);
    284     ADD_TEST(test_bio_get_mem);
    285     ADD_TEST(test_bio_new_mem_buf);
    286     ADD_TEST(test_bio_rdonly_mem_buf);
    287     ADD_TEST(test_bio_rdwr_rdonly);
    288     ADD_TEST(test_bio_nonclear_rst);
    289     ADD_TEST(test_bio_i2d_ASN1_mime);
    290     return 1;
    291 }
    292