Fix possible infinite loop in pem_read_bio_key_decoder()
authorTomas Mraz <tomas@openssl.org>
Mon, 24 May 2021 16:47:45 +0000 (18:47 +0200)
committerTomas Mraz <tomas@openssl.org>
Wed, 26 May 2021 11:04:38 +0000 (13:04 +0200)
There could be an infinite loop if no read happened.

Fixes #15426

Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15441)

crypto/pem/pem_pkey.c

index adbf8bcfe70413b936f81bb3714875b1f511d79b..becf7e277cf74ae18fd32ccbe9459d68aeed4310 100644 (file)
@@ -36,6 +36,11 @@ static EVP_PKEY *pem_read_bio_key_decoder(BIO *bp, EVP_PKEY **x,
 {
     EVP_PKEY *pkey = NULL;
     OSSL_DECODER_CTX *dctx = NULL;
+    int pos, newpos;
+
+    if ((pos = BIO_tell(bp)) < 0)
+        /* We can depend on BIO_tell() thanks to the BIO_f_readbuffer() */
+        return NULL;
 
     dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "PEM", NULL, NULL,
                                          selection, libctx, propq);
@@ -50,8 +55,10 @@ static EVP_PKEY *pem_read_bio_key_decoder(BIO *bp, EVP_PKEY **x,
         goto err;
 
     while (!OSSL_DECODER_from_bio(dctx, bp) || pkey == NULL)
-        if (BIO_eof(bp) != 0)
+        if (BIO_eof(bp) != 0 || (newpos = BIO_tell(bp)) < 0 || newpos <= pos)
             goto err;
+        else
+            pos = newpos;
 
     if (!evp_keymgmt_util_has(pkey, selection)) {
         EVP_PKEY_free(pkey);