From: Matt Caswell Date: Wed, 25 Nov 2020 13:13:24 +0000 (+0000) Subject: Fix instances of pointer addition with the NULL pointer X-Git-Tag: openssl-3.0.0-alpha10~226 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a07dc8167ba79efe739fef18d7e2ef823bef16c9;p=thirdparty%2Fopenssl.git Fix instances of pointer addition with the NULL pointer 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 Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/13513) --- diff --git a/crypto/asn1/a_int.c b/crypto/asn1/a_int.c index a90f8c7fb33..98c759cc93e 100644 --- a/crypto/asn1/a_int.c +++ b/crypto/asn1/a_int.c @@ -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); diff --git a/crypto/bio/bss_mem.c b/crypto/bio/bss_mem.c index 656c44b7af1..ad7e8a61062 100644 --- a/crypto/bio/bss_mem.c +++ b/crypto/bio/bss_mem.c @@ -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: diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c index f1df0a40b16..7695699c739 100644 --- a/crypto/pem/pem_lib.c +++ b/crypto/pem/pem_lib.c @@ -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); diff --git a/providers/implementations/ciphers/cipher_aes_ocb.c b/providers/implementations/ciphers/cipher_aes_ocb.c index 7cb3f6a764b..fa2c014a01e 100644 --- a/providers/implementations/ciphers/cipher_aes_ocb.c +++ b/providers/implementations/ciphers/cipher_aes_ocb.c @@ -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; diff --git a/test/filterprov.c b/test/filterprov.c index 5b9cd306682..3cfb095ae51 100644 --- a/test/filterprov.c +++ b/test/filterprov.c @@ -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'; diff --git a/test/testutil/format_output.c b/test/testutil/format_output.c index e2ee98cfd80..e101a7ecefb 100644 --- a/test/testutil/format_output.c +++ b/test/testutil/format_output.c @@ -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;