cred-encoding: Avoid potential use after free when caching encodings
The pattern currently is to call get_cache(), generate the encoding if that failed and then store it with cache(). The latter adopts the passed encoding and frees any stored encoding. However, the latter means that if two threads concurrently fail to get a cached encoding and then both generate and store one, one of the threads might use an encoding that was freed by the other thread. Since encodings are not expected to change, we can avoid this issue by not replacing an existing cache entry and instead return that (while freeing the passed value instead of the cached one). Closes strongswan/strongswan#1231
This commit is contained in:
@@ -646,7 +646,7 @@ METHOD(private_key_t, get_fingerprint, bool,
|
||||
this->set, type, fp);
|
||||
if (success)
|
||||
{
|
||||
lib->encoding->cache(lib->encoding, type, this, *fp);
|
||||
lib->encoding->cache(lib->encoding, type, this, fp);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -267,7 +267,7 @@ METHOD(public_key_t, get_fingerprint, bool,
|
||||
this->set, type, fp);
|
||||
if (success)
|
||||
{
|
||||
lib->encoding->cache(lib->encoding, type, this, *fp);
|
||||
lib->encoding->cache(lib->encoding, type, this, fp);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ bool botan_get_fingerprint(botan_pubkey_t pubkey, void *cache,
|
||||
|
||||
if (cache)
|
||||
{
|
||||
lib->encoding->cache(lib->encoding, type, cache, *fp);
|
||||
lib->encoding->cache(lib->encoding, type, cache, fp);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ METHOD(private_key_t, get_fingerprint, bool,
|
||||
success = curve25519_public_key_fingerprint(this->pubkey, type, fp);
|
||||
if (success)
|
||||
{
|
||||
lib->encoding->cache(lib->encoding, type, this, *fp);
|
||||
lib->encoding->cache(lib->encoding, type, this, fp);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ METHOD(public_key_t, get_fingerprint, bool,
|
||||
success = curve25519_public_key_fingerprint(this->pubkey, type, fp);
|
||||
if (success)
|
||||
{
|
||||
lib->encoding->cache(lib->encoding, type, this, *fp);
|
||||
lib->encoding->cache(lib->encoding, type, this, fp);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ bool openssl_ed_fingerprint(EVP_PKEY *key, cred_encoding_type_t type,
|
||||
return FALSE;
|
||||
}
|
||||
hasher->destroy(hasher);
|
||||
lib->encoding->cache(lib->encoding, type, key, *fp);
|
||||
lib->encoding->cache(lib->encoding, type, key, fp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ bool openssl_fingerprint(EVP_PKEY *key, cred_encoding_type_t type, chunk_t *fp)
|
||||
}
|
||||
free(enc.ptr);
|
||||
hasher->destroy(hasher);
|
||||
lib->encoding->cache(lib->encoding, type, key, *fp);
|
||||
lib->encoding->cache(lib->encoding, type, key, fp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -430,7 +430,7 @@ static bool fingerprint_ecdsa(private_pkcs11_public_key_t *this,
|
||||
}
|
||||
hasher->destroy(hasher);
|
||||
chunk_clear(&asn1);
|
||||
lib->encoding->cache(lib->encoding, type, this, *fp);
|
||||
lib->encoding->cache(lib->encoding, type, this, fp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -253,7 +253,7 @@ bool wolfssl_ec_fingerprint(ecc_key *ec, cred_encoding_type_t type, chunk_t *fp)
|
||||
return FALSE;
|
||||
}
|
||||
hasher->destroy(hasher);
|
||||
lib->encoding->cache(lib->encoding, type, ec, *fp);
|
||||
lib->encoding->cache(lib->encoding, type, ec, fp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@ bool wolfssl_ed_fingerprint(wolfssl_ed_key *key, key_type_t key_type,
|
||||
}
|
||||
else
|
||||
{
|
||||
lib->encoding->cache(lib->encoding, type, key, *fp);
|
||||
lib->encoding->cache(lib->encoding, type, key, fp);
|
||||
success = TRUE;
|
||||
}
|
||||
DESTROY_IF(hasher);
|
||||
|
||||
@@ -370,7 +370,7 @@ bool wolfssl_rsa_fingerprint(RsaKey *rsa, cred_encoding_type_t type,
|
||||
}
|
||||
else
|
||||
{
|
||||
lib->encoding->cache(lib->encoding, type, rsa, *fp);
|
||||
lib->encoding->cache(lib->encoding, type, rsa, fp);
|
||||
success = TRUE;
|
||||
}
|
||||
DESTROY_IF(hasher);
|
||||
|
||||
Reference in New Issue
Block a user