mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-20 13:21:29 +02:00
BUG/MINOR: ocsp: Crash when updating CA during ocsp updates
If an ocsp response is set to be updated automatically and some certificate or CA updates are performed on the CLI, if the CLI update happens while the OCSP response is being updated and is then detached from the udapte tree, it might be wrongly inserted into the update tree in 'ssl_sock_load_ocsp', and then reinserted when the update finishes. The update tree then gets corrupted and we could end up crashing when accessing other nodes in the ocsp response update tree. This patch must be backported up to 2.8. This patch fixes GitHub #3100.
This commit is contained in:
parent
157852ce99
commit
167ea8fc7b
@ -53,7 +53,7 @@ int ssl_ocsp_check_response(STACK_OF(X509) *chain, X509 *issuer,
|
|||||||
int ssl_create_ocsp_update_task(char **err);
|
int ssl_create_ocsp_update_task(char **err);
|
||||||
void ssl_destroy_ocsp_update_task(void);
|
void ssl_destroy_ocsp_update_task(void);
|
||||||
|
|
||||||
int ssl_ocsp_update_insert(struct certificate_ocsp *ocsp);
|
int ssl_ocsp_update_insert(struct certificate_ocsp *ocsp, int needs_locking);
|
||||||
|
|
||||||
int ocsp_update_init(void *value, char *buf, struct ckch_data *d, int cli, const char *filename, int linenum, char **err);
|
int ocsp_update_init(void *value, char *buf, struct ckch_data *d, int cli, const char *filename, int linenum, char **err);
|
||||||
|
|
||||||
|
@ -1048,7 +1048,7 @@ static inline void ssl_ocsp_set_next_update(struct certificate_ocsp *ocsp)
|
|||||||
* defined in order to avoid updating too often responses that have a really
|
* defined in order to avoid updating too often responses that have a really
|
||||||
* short expire time or even no 'Next Update' at all.
|
* short expire time or even no 'Next Update' at all.
|
||||||
*/
|
*/
|
||||||
int ssl_ocsp_update_insert(struct certificate_ocsp *ocsp)
|
int ssl_ocsp_update_insert(struct certificate_ocsp *ocsp, int needs_locking)
|
||||||
{
|
{
|
||||||
/* Set next_update based on current time and the various OCSP
|
/* Set next_update based on current time and the various OCSP
|
||||||
* minimum/maximum update times.
|
* minimum/maximum update times.
|
||||||
@ -1057,14 +1057,16 @@ int ssl_ocsp_update_insert(struct certificate_ocsp *ocsp)
|
|||||||
|
|
||||||
ocsp->fail_count = 0;
|
ocsp->fail_count = 0;
|
||||||
|
|
||||||
HA_SPIN_LOCK(OCSP_LOCK, &ocsp_tree_lock);
|
if (needs_locking)
|
||||||
|
HA_SPIN_LOCK(OCSP_LOCK, &ocsp_tree_lock);
|
||||||
ocsp->updating = 0;
|
ocsp->updating = 0;
|
||||||
/* An entry with update_once set to 1 was only supposed to be updated
|
/* An entry with update_once set to 1 was only supposed to be updated
|
||||||
* once, it does not need to be reinserted into the update tree.
|
* once, it does not need to be reinserted into the update tree.
|
||||||
*/
|
*/
|
||||||
if (!ocsp->update_once)
|
if (!ocsp->update_once)
|
||||||
eb64_insert(&ocsp_update_tree, &ocsp->next_update);
|
eb64_insert(&ocsp_update_tree, &ocsp->next_update);
|
||||||
HA_SPIN_UNLOCK(OCSP_LOCK, &ocsp_tree_lock);
|
if (needs_locking)
|
||||||
|
HA_SPIN_UNLOCK(OCSP_LOCK, &ocsp_tree_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1292,7 +1294,7 @@ static struct task *ssl_ocsp_update_responses(struct task *task, void *context,
|
|||||||
ssl_ocsp_send_log();
|
ssl_ocsp_send_log();
|
||||||
|
|
||||||
/* Reinsert the entry into the update list so that it can be updated later */
|
/* Reinsert the entry into the update list so that it can be updated later */
|
||||||
ssl_ocsp_update_insert(ocsp);
|
ssl_ocsp_update_insert(ocsp, 0);
|
||||||
/* Release the reference kept on the updated ocsp response. */
|
/* Release the reference kept on the updated ocsp response. */
|
||||||
ssl_sock_free_ocsp_instance(ctx->cur_ocsp);
|
ssl_sock_free_ocsp_instance(ctx->cur_ocsp);
|
||||||
ctx->cur_ocsp = NULL;
|
ctx->cur_ocsp = NULL;
|
||||||
|
@ -1499,7 +1499,7 @@ static int ssl_sock_load_ocsp(const char *path, SSL_CTX *ctx, struct ckch_store
|
|||||||
memcpy(iocsp->path, path, path_len + 1);
|
memcpy(iocsp->path, path, path_len + 1);
|
||||||
|
|
||||||
if (enable_auto_update) {
|
if (enable_auto_update) {
|
||||||
ssl_ocsp_update_insert(iocsp);
|
ssl_ocsp_update_insert(iocsp, 1);
|
||||||
/* If we are during init the update task is not
|
/* If we are during init the update task is not
|
||||||
* scheduled yet so a wakeup won't do anything.
|
* scheduled yet so a wakeup won't do anything.
|
||||||
* Otherwise, if the OCSP was added through the CLI, we
|
* Otherwise, if the OCSP was added through the CLI, we
|
||||||
@ -1517,18 +1517,28 @@ static int ssl_sock_load_ocsp(const char *path, SSL_CTX *ctx, struct ckch_store
|
|||||||
* prior to the activation of the ocsp auto update and in such a
|
* prior to the activation of the ocsp auto update and in such a
|
||||||
* case we must "force" insertion in the auto update tree.
|
* case we must "force" insertion in the auto update tree.
|
||||||
*/
|
*/
|
||||||
|
HA_SPIN_LOCK(OCSP_LOCK, &ocsp_tree_lock);
|
||||||
if (iocsp->next_update.node.leaf_p == NULL) {
|
if (iocsp->next_update.node.leaf_p == NULL) {
|
||||||
ssl_ocsp_update_insert(iocsp);
|
/* We might be facing an entry that is currently being
|
||||||
/* If we are during init the update task is not
|
* updated, which can take some time (especially if the
|
||||||
* scheduled yet so a wakeup won't do anything.
|
* ocsp responder is unreachable).
|
||||||
* Otherwise, if the OCSP was added through the CLI, we
|
* The entry will be reinserted by the update task, it
|
||||||
* wake the task up to manage the case of a new entry
|
* mustn't be reinserted here.
|
||||||
* that needs to be updated before the previous first
|
|
||||||
* entry.
|
|
||||||
*/
|
*/
|
||||||
if (ocsp_update_task)
|
if (!iocsp->updating) {
|
||||||
task_wakeup(ocsp_update_task, TASK_WOKEN_MSG);
|
ssl_ocsp_update_insert(iocsp, 0);
|
||||||
|
/* If we are during init the update task is not
|
||||||
|
* scheduled yet so a wakeup won't do anything.
|
||||||
|
* Otherwise, if the OCSP was added through the CLI, we
|
||||||
|
* wake the task up to manage the case of a new entry
|
||||||
|
* that needs to be updated before the previous first
|
||||||
|
* entry.
|
||||||
|
*/
|
||||||
|
if (ocsp_update_task)
|
||||||
|
task_wakeup(ocsp_update_task, TASK_WOKEN_MSG);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
HA_SPIN_UNLOCK(OCSP_LOCK, &ocsp_tree_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user