Fix corruption when searching for CRLs in hashed directories#20076
Fix corruption when searching for CRLs in hashed directories#20076hlandau wants to merge 1 commit intoopenssl:masterfrom
Conversation
The by_dir certificate/CRL lookup code uses an OPENSSL_STACK to track how many sequentially numbered CRL files have been loaded for a given X509_NAME hash which is being requested. This avoids loading already loaded CRL files and repeated stat() calls. This OPENSSL_STACK is searched using sk_find, however this mutates the OPENSSL_STACK unless it is known to be sorted. This operation therefore requires a write lock, which was not taken. Fix this issue by sorting the OPENSSL_STACK whenever it is mutated. This guarantees no mutation will occur during sk_find. This is chosen over taking a write lock during sk_find as retrieving a CRL by X509_NAME is assumed to be a hotter path than the case where a new CRL is installed. Also optimise the code by avoiding creating the structure to track the last CRL file sequence number in the circumstance where it would match the initial value, namely where no CRL with the given hash is installed.
|
This looks like it might affect quite a few other API's.. There is the sk_find_ex and sk_find_all variants also... |
|
@slontis Yeah. A more general fix is needed and will be worked on. This is just a priority fix for a crash that was actually materialising. |
This is also the correct fix even if we had a more general solution. Sorting the stack at the appropriate time is a good thing to do. |
|
24 hours has passed since 'approval: done' was set, but as this PR has been updated in that time the label 'approval: ready to merge' is not being automatically set. Please review the updates and set the label manually. |
The by_dir certificate/CRL lookup code uses an OPENSSL_STACK to track how many sequentially numbered CRL files have been loaded for a given X509_NAME hash which is being requested. This avoids loading already loaded CRL files and repeated stat() calls. This OPENSSL_STACK is searched using sk_find, however this mutates the OPENSSL_STACK unless it is known to be sorted. This operation therefore requires a write lock, which was not taken. Fix this issue by sorting the OPENSSL_STACK whenever it is mutated. This guarantees no mutation will occur during sk_find. This is chosen over taking a write lock during sk_find as retrieving a CRL by X509_NAME is assumed to be a hotter path than the case where a new CRL is installed. Also optimise the code by avoiding creating the structure to track the last CRL file sequence number in the circumstance where it would match the initial value, namely where no CRL with the given hash is installed. Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Paul Dale <[email protected]> (Merged from #20076)
The by_dir certificate/CRL lookup code uses an OPENSSL_STACK to track how many sequentially numbered CRL files have been loaded for a given X509_NAME hash which is being requested. This avoids loading already loaded CRL files and repeated stat() calls. This OPENSSL_STACK is searched using sk_find, however this mutates the OPENSSL_STACK unless it is known to be sorted. This operation therefore requires a write lock, which was not taken. Fix this issue by sorting the OPENSSL_STACK whenever it is mutated. This guarantees no mutation will occur during sk_find. This is chosen over taking a write lock during sk_find as retrieving a CRL by X509_NAME is assumed to be a hotter path than the case where a new CRL is installed. Also optimise the code by avoiding creating the structure to track the last CRL file sequence number in the circumstance where it would match the initial value, namely where no CRL with the given hash is installed. Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Paul Dale <[email protected]> (Merged from #20076) (cherry picked from commit 3147785)
|
Merged to 3.0, 3.1 and master. |
The by_dir certificate/CRL lookup code uses an OPENSSL_STACK to track how many sequentially numbered CRL files have been loaded for a given X509_NAME hash which is being requested. This avoids loading already loaded CRL files and repeated stat() calls. This OPENSSL_STACK is searched using sk_find, however this mutates the OPENSSL_STACK unless it is known to be sorted. This operation therefore requires a write lock, which was not taken. Fix this issue by sorting the OPENSSL_STACK whenever it is mutated. This guarantees no mutation will occur during sk_find. This is chosen over taking a write lock during sk_find as retrieving a CRL by X509_NAME is assumed to be a hotter path than the case where a new CRL is installed. Also optimise the code by avoiding creating the structure to track the last CRL file sequence number in the circumstance where it would match the initial value, namely where no CRL with the given hash is installed. Reviewed-by: Tomas Mraz <[email protected]> Reviewed-by: Paul Dale <[email protected]> (Merged from #20076) (cherry picked from commit 3147785)
|
Backport to 1.1.1 in #20127. |
The by_dir certificate/CRL lookup code uses an OPENSSL_STACK to track how many sequentially numbered CRL files have been loaded for a given X509_NAME hash which is being requested. This avoids loading already loaded CRL files and repeated stat() calls.
This OPENSSL_STACK is searched using sk_find, however this mutates the OPENSSL_STACK unless it is known to be sorted. This operation therefore requires a write lock, which was not taken.
Fix this issue by sorting the OPENSSL_STACK whenever it is mutated. This guarantees no mutation will occur during sk_find. This is chosen over taking a write lock during sk_find as retrieving a CRL by X509_NAME is assumed to be a hotter path than the case where a new CRL is installed.
Also optimise the code by avoiding creating the structure to track the last CRL file sequence number in the circumstance where it would match the initial value, namely where no CRL with the given hash is installed.
Unsure about how we should test this.
Have identified more unsafe use of sk_find which will need further work. This should cherry-pick cleanly to 3.1 and 3.0.