postgres.git / summary / log / commit / refs

commit    5ba1df0f14d19a32c69adf97d452726fa6a28e02
Author:   Michael Paquier <michael@paquier.xyz>
Date:     Tue Dec 08 06:22:53 2020 +0000

    pgcrypto: Detect errors with EVP calls from OpenSSL
    
    The following routines are called within pgcrypto when handling digests
    but there were no checks for failures:
    - EVP_MD_CTX_size (can fail with -1 as of 3.0.0)
    - EVP_MD_CTX_block_size (can fail with -1 as of 3.0.0)
    - EVP_DigestInit_ex
    - EVP_DigestUpdate
    - EVP_DigestFinal_ex
    
    A set of elog(ERROR) is added by this commit to detect such failures,
    that should never happen except in the event of a processing failure
    internal to OpenSSL.
    
    Note that it would be possible to use ERR_reason_error_string() to get
    more context about such errors, but these refer mainly to the internals
    of OpenSSL, so it is not really obvious how useful that would be.  This
    is left out for simplicity.
    
    Per report from Coverity.  Thanks to Tom Lane for the discussion.
    
    Backpatch-through: 9.5


contrib/pgcrypto/openssl.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c index 7aab0f4134a..cfb73de7191 100644 --- a/contrib/pgcrypto/openssl.c +++ b/contrib/pgcrypto/openssl.c @@ -115,16 +115,24 @@ static unsigned digest_result_size(PX_MD *h) { OSSLDigest *digest = (OSSLDigest *) h->p.ptr; + int result = EVP_MD_CTX_size(digest->ctx); - return EVP_MD_CTX_size(digest->ctx); + if (result < 0) + elog(ERROR, "EVP_MD_CTX_size() failed"); + + return result; } static unsigned digest_block_size(PX_MD *h) { OSSLDigest *digest = (OSSLDigest *) h->p.ptr; + int result = EVP_MD_CTX_block_size(digest->ctx); + + if (result < 0) + elog(ERROR, "EVP_MD_CTX_block_size() failed"); - return EVP_MD_CTX_block_size(digest->ctx); + return result; } static void @@ -132,7 +140,8 @@ digest_reset(PX_MD *h) { OSSLDigest *digest = (OSSLDigest *) h->p.ptr; - EVP_DigestInit_ex(digest->ctx, digest->algo, NULL); + if (!EVP_DigestInit_ex(digest->ctx, digest->algo, NULL)) + elog(ERROR, "EVP_DigestInit_ex() failed"); } static void @@ -140,7 +149,8 @@ digest_update(PX_MD *h, const uint8 *data, unsigned dlen) { OSSLDigest *digest = (OSSLDigest *) h->p.ptr; - EVP_DigestUpdate(digest->ctx, data, dlen); + if (!EVP_DigestUpdate(digest->ctx, data, dlen)) + elog(ERROR, "EVP_DigestUpdate() failed"); } static void @@ -148,7 +158,8 @@ digest_finish(PX_MD *h, uint8 *dst) { OSSLDigest *digest = (OSSLDigest *) h->p.ptr; - EVP_DigestFinal_ex(digest->ctx, dst, NULL); + if (!EVP_DigestFinal_ex(digest->ctx, dst, NULL)) + elog(ERROR, "EVP_DigestFinal_ex() failed"); } static void [parent: d137b14c3cec]