Fix instances of pointer addition with the NULL pointer
authorMatt Caswell <matt@openssl.org>
Wed, 25 Nov 2020 13:13:24 +0000 (13:13 +0000)
committerMatt Caswell <matt@openssl.org>
Mon, 30 Nov 2020 10:37:14 +0000 (10:37 +0000)
Addition using the NULL pointer (even when adding 0) is undefined
behaviour. Recent versions of ubsan are now complaining about this, so
we fix various instances.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13513)

crypto/asn1/a_int.c
crypto/bio/bss_mem.c
crypto/pem/pem_lib.c
providers/implementations/ciphers/cipher_aes_ocb.c
test/filterprov.c
test/testutil/format_output.c

index a90f8c7fb3347b9180ef115e6053ff90da017376..98c759cc93e1d6f2ec481c76d8ff246e1f77f55b 100644 (file)
@@ -79,8 +79,14 @@ static void twos_complement(unsigned char *dst, const unsigned char *src,
     unsigned int carry = pad & 1;
 
     /* Begin at the end of the encoding */
-    dst += len;
-    src += len;
+    if (len != 0) {
+        /*
+         * if len == 0 then src/dst could be NULL, and this would be undefined
+         * behaviour.
+         */
+        dst += len;
+        src += len;
+    }
     /* two's complement value: ~value + 1 */
     while (len-- != 0) {
         *(--dst) = (unsigned char)(carry += *(--src) ^ pad);
index 656c44b7af1a90bb433acc76be21138e2bcc2905..ad7e8a6106223c4d383754b20efd20814b841850 100644 (file)
@@ -299,7 +299,7 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
         ret = (long)bm->length;
         if (ptr != NULL) {
             pptr = (char **)ptr;
-            *pptr = (char *)&(bm->data[0]);
+            *pptr = (char *)(bm->data);
         }
         break;
     case BIO_C_SET_BUF_MEM:
index f1df0a40b165d634fe08b27bb351f5f9f1a23895..7695699c739bf089259e77946a74314e0298a972 100644 (file)
@@ -917,18 +917,13 @@ err:
 int PEM_read_bio_ex(BIO *bp, char **name_out, char **header,
                     unsigned char **data, long *len_out, unsigned int flags)
 {
-    EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
+    EVP_ENCODE_CTX *ctx = NULL;
     const BIO_METHOD *bmeth;
     BIO *headerB = NULL, *dataB = NULL;
     char *name = NULL;
     int len, taillen, headerlen, ret = 0;
     BUF_MEM * buf_mem;
 
-    if (ctx == NULL) {
-        ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
-        return 0;
-    }
-
     *len_out = 0;
     *name_out = *header = NULL;
     *data = NULL;
@@ -951,9 +946,20 @@ int PEM_read_bio_ex(BIO *bp, char **name_out, char **header,
     if (!get_header_and_data(bp, &headerB, &dataB, name, flags))
         goto end;
 
-    EVP_DecodeInit(ctx);
     BIO_get_mem_ptr(dataB, &buf_mem);
     len = buf_mem->length;
+
+    /* There was no data in the PEM file */
+    if (len == 0)
+        goto end;
+
+    ctx = EVP_ENCODE_CTX_new();
+    if (ctx == NULL) {
+        ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE);
+        goto end;
+    }
+
+    EVP_DecodeInit(ctx);
     if (EVP_DecodeUpdate(ctx, (unsigned char*)buf_mem->data, &len,
                          (unsigned char*)buf_mem->data, len) < 0
             || EVP_DecodeFinal(ctx, (unsigned char*)&(buf_mem->data[len]),
@@ -964,9 +970,6 @@ int PEM_read_bio_ex(BIO *bp, char **name_out, char **header,
     len += taillen;
     buf_mem->length = len;
 
-    /* There was no data in the PEM file; avoid malloc(0). */
-    if (len == 0)
-        goto end;
     headerlen = BIO_get_mem_data(headerB, NULL);
     *header = pem_malloc(headerlen + 1, flags);
     *data = pem_malloc(len, flags);
index 7cb3f6a764b4f0b3a51d9df8d983d1721111b4fb..fa2c014a01ec7614456b7827fb4f1ed2aceba499 100644 (file)
@@ -177,7 +177,8 @@ static int aes_ocb_block_update_internal(PROV_AES_OCB_CTX *ctx,
         }
         *bufsz = 0;
         outlint = AES_BLOCK_SIZE;
-        out += AES_BLOCK_SIZE;
+        if (out != NULL)
+            out += AES_BLOCK_SIZE;
     }
     if (nextblocks > 0) {
         outlint += nextblocks;
index 5b9cd306682e7ac4c0daf2410d9da1e1c96d2d65..3cfb095ae517738daeeab2cc5bd2438f3be3dbf3 100644 (file)
@@ -167,7 +167,7 @@ int filter_provider_set_filter(int operation, const char *filterstr)
     if (globs->num_dispatch >= MAX_FILTERS)
         goto err;
 
-    for (name = filterstrtmp; !last; name = sep + 1) {
+    for (name = filterstrtmp; !last; name = (sep == NULL ? NULL : sep + 1)) {
         sep = strstr(name, ":");
         if (sep != NULL)
             *sep = '\0';
index e2ee98cfd80283a44e54731afe2a287c4f28cc3c..e101a7ecefb17636c50f8878e1ebd6bddd490cc3 100644 (file)
@@ -108,8 +108,10 @@ static void test_fail_string_common(const char *prefix, const char *file,
             if (diff && i > 0)
                 test_printf_stderr("%4s    %s\n", "", bdiff);
         }
-        m1 += n1;
-        m2 += n2;
+        if (m1 != NULL)
+            m1 += n1;
+        if (m2 != NULL)
+            m2 += n2;
         l1 -= n1;
         l2 -= n2;
         cnt += width;
@@ -497,8 +499,10 @@ static void test_fail_memory_common(const char *prefix, const char *file,
             if (diff && i > 0)
                 test_printf_stderr("%4s  %s\n", "", bdiff);
         }
-        m1 += n1;
-        m2 += n2;
+        if (m1 != NULL)
+            m1 += n1;
+        if (m2 != NULL)
+            m2 += n2;
         l1 -= n1;
         l2 -= n2;
         cnt += bytes;