Skip to content

EVP_CIPHER_CTX_copy() fails to copy dasync ENGINE data correctly #16844

@mattcaswell

Description

@mattcaswell

If you use EVP_CIPHER_CTX_copy() on a an existing EVP_CIPHER_CTX that was initialised using a cipher from the dasync ENGINE, then subsequently freeing the source and destination EVP_CIPHER_CTX objects results in a double free.

The reason is that, by default, the copy operation simply does a memcpy on the internal cipher data:

openssl/crypto/evp/evp_enc.c

Lines 1396 to 1412 in d5d95da

if (in->cipher_data && in->cipher->ctx_size) {
out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size);
if (out->cipher_data == NULL) {
out->cipher = NULL;
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
return 0;
}
memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size);
}
if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY)
if (!in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out)) {
out->cipher = NULL;
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
return 0;
}
return 1;

Unfortunately, for the dasync engine, this internal cipher data contains pointers to other data which is managed internally to the daysnc engine. When the source and destination EVP_CIPHER_CTX objects subsequently get freed the internal pointers (which are identical) are also freed twice - and hence a double free occurs.

To avoid this problem, engines that need to are supposed to use the EVP_CIPH_CUSTOM_COPY flag, but the dasync engine does not do this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    branch: 1.1.1Applies to OpenSSL_1_1_1-stable branch (EOL)branch: 3.0Applies to openssl-3.0 branchbranch: masterApplies to master branchtriaged: bugThe issue/pr is/fixes a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions