Viktor,
Thank you for taking a look.
We are not invoking either of the API X509_STORE_CTX_get0_chain/X509_STORE_CTX_get1_chain
We invoke X509_verify_cert() during the certification verification and this fails (expectedly due to the missing CA certificate), so we invoke X509_STORE_CTX_free to clean up the "X509_STORE_CTX" context and hit this crash (this is not seen always)
X509_STORE_new()
X509_STORE_CTX_new()
X509_STORE_set_verify_cb_func
X509_STORE_set_default_paths
X509_STORE_load_locations
X509_STORE_CTX_init
X509_STORE_CTX_set_flags
X509_verify_cert --------------------> Fails with error X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY as CA certificate is not present.
/* Cleanup. */
X509_STORE_CTX_free(pContext); -------------------->Crash seen here in sk_X509_pop_free
360 void OPENSSL_sk_pop_free(OPENSSL_STACK *st, OPENSSL_sk_freefunc func)
361 {
362 int i;
363
364 if (st == NULL)
365 return;
366 for (i = 0; i < st->num; i++)
367 if (st->data[i] != NULL)---------------------> Crash seen here
368 func((char *)st->data[i]);
369 OPENSSL_sk_free(st);
370 }
Thanks
Bala
On Monday, 16 August, 2021, 11:40:24 pm IST, Viktor Dukhovni <openssl-users@xxxxxxxxxxxx> wrote:
> On 16 Aug 2021, at 5:58 am, Bala Duvvuri via openssl-users <openssl-users@xxxxxxxxxxx> wrote:
>
> We are using OpenSSl version 1.1.1d in our program and crash is being seen in "OPENSSL_sk_pop_free" API, we invoke this API in our certificate verification API. Since crash is not seen always, trying to understand from OpenSSL code, when can this occur?
>
> Below is the bt of the crash
>
> #0 0x0f31f438 in OPENSSL_sk_pop_free (st=0x1041de20, func=0xf34d5b0 <X509_free>) at crypto/stack/stack.c:367
> #1 0x0f344c74 in sk_X509_pop_free (freefunc=<optimized out>, sk=<optimized out>) at include/openssl/x509.h:99
> #2 X509_STORE_CTX_cleanup (ctx=ctx@entry=0x1041ba70) at crypto/x509/x509_vfy.c:2454
> #3 0x0f344cf4 in X509_STORE_CTX_free (ctx=ctx@entry=0x1041ba70) at crypto/x509/x509_vfy.c:2281
The call in question frees the certificate chain built by X509_verify_cert().
sk_X509_pop_free(ctx->chain, X509_free);
That chain is owned by the X509_STORE_CTX. You probably made the
mistake of freeing it (or one of the certificates in question) yourself.
There are two functions for accessing the built chain:
STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx)
{
return ctx->chain;
}
STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
{
if (!ctx->chain)
return NULL;
return X509_chain_up_ref(ctx->chain);
}
If you call X509_STORE_CTX_get0_chain(3), you MUST NOT free the result.
If you call X509_STORE_CTX_get1_chain(3), you own the chain copy, and
should free the result when you no longer need it.
--
Viktor.
>
> We are using OpenSSl version 1.1.1d in our program and crash is being seen in "OPENSSL_sk_pop_free" API, we invoke this API in our certificate verification API. Since crash is not seen always, trying to understand from OpenSSL code, when can this occur?
>
> Below is the bt of the crash
>
> #0 0x0f31f438 in OPENSSL_sk_pop_free (st=0x1041de20, func=0xf34d5b0 <X509_free>) at crypto/stack/stack.c:367
> #1 0x0f344c74 in sk_X509_pop_free (freefunc=<optimized out>, sk=<optimized out>) at include/openssl/x509.h:99
> #2 X509_STORE_CTX_cleanup (ctx=ctx@entry=0x1041ba70) at crypto/x509/x509_vfy.c:2454
> #3 0x0f344cf4 in X509_STORE_CTX_free (ctx=ctx@entry=0x1041ba70) at crypto/x509/x509_vfy.c:2281
The call in question frees the certificate chain built by X509_verify_cert().
sk_X509_pop_free(ctx->chain, X509_free);
That chain is owned by the X509_STORE_CTX. You probably made the
mistake of freeing it (or one of the certificates in question) yourself.
There are two functions for accessing the built chain:
STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx)
{
return ctx->chain;
}
STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
{
if (!ctx->chain)
return NULL;
return X509_chain_up_ref(ctx->chain);
}
If you call X509_STORE_CTX_get0_chain(3), you MUST NOT free the result.
If you call X509_STORE_CTX_get1_chain(3), you own the chain copy, and
should free the result when you no longer need it.
--
Viktor.