From: Matt Caswell Date: Fri, 6 Oct 2023 14:56:15 +0000 (+0100) Subject: When calling ossl_crypto_condvar_wait_timeout() we must use real time X-Git-Tag: openssl-3.2.0-beta1~108 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2b8d81534479b161dda063477272363fb2caef08;p=thirdparty%2Fopenssl.git When calling ossl_crypto_condvar_wait_timeout() we must use real time Although many of the QUIC tests use fake time, the time we pass to the ossl_crypto_condvar_wait_timeout() must be a real time. Passing fake time was causing the QUIC tserver test to hang because ossl_crypto_convar_wait_timeout() always timed out immediately and never relinquished the CPU. If using fake time we adjust the time to real time just before using it. Fixes #22020 Reviewed-by: Hugo Landau Reviewed-by: Paul Dale Reviewed-by: Richard Levitte Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22301) --- diff --git a/include/internal/quic_thread_assist.h b/include/internal/quic_thread_assist.h index 7d1b47453a1..592c2ffabff 100644 --- a/include/internal/quic_thread_assist.h +++ b/include/internal/quic_thread_assist.h @@ -12,6 +12,7 @@ # include # include "internal/thread.h" +# include "internal/time.h" # if defined(OPENSSL_NO_QUIC) || defined(OPENSSL_NO_THREAD_POOL) # define OPENSSL_NO_QUIC_THREAD_ASSIST @@ -46,6 +47,8 @@ typedef struct quic_thread_assist_st { CRYPTO_CONDVAR *cv; CRYPTO_THREAD *t; int teardown, joined; + OSSL_TIME (*now_cb)(void *arg); + void *now_cb_arg; } QUIC_THREAD_ASSIST; /* @@ -55,7 +58,9 @@ typedef struct quic_thread_assist_st { * not affect the state of the mutex. */ int ossl_quic_thread_assist_init_start(QUIC_THREAD_ASSIST *qta, - QUIC_CHANNEL *ch); + QUIC_CHANNEL *ch, + OSSL_TIME (*now_cb)(void *arg), + void *now_cb_arg); /* * Request the thread assist helper to begin stopping the assist thread. This diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index cb927fa52d1..86020a450a9 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -1532,7 +1532,9 @@ static int ensure_channel_started(QCTX *ctx) #if !defined(OPENSSL_NO_QUIC_THREAD_ASSIST) if (qc->is_thread_assisted) - if (!ossl_quic_thread_assist_init_start(&qc->thread_assist, qc->ch)) { + if (!ossl_quic_thread_assist_init_start(&qc->thread_assist, qc->ch, + qc->override_now_cb, + qc->override_now_cb_arg)) { QUIC_RAISE_NON_NORMAL_ERROR(ctx, ERR_R_INTERNAL_ERROR, "failed to start assist thread"); return 0; diff --git a/ssl/quic/quic_thread_assist.c b/ssl/quic/quic_thread_assist.c index b5c1829e8e6..e1de72a910a 100644 --- a/ssl/quic/quic_thread_assist.c +++ b/ssl/quic/quic_thread_assist.c @@ -28,11 +28,24 @@ static unsigned int assist_thread_main(void *arg) rtor = ossl_quic_channel_get_reactor(qta->ch); for (;;) { + OSSL_TIME deadline; + if (qta->teardown) break; - ossl_crypto_condvar_wait_timeout(qta->cv, m, - ossl_quic_reactor_get_tick_deadline(rtor)); + deadline = ossl_quic_reactor_get_tick_deadline(rtor); + if (qta->now_cb != NULL + && !ossl_time_is_zero(deadline) + && !ossl_time_is_infinite(deadline)) { + /* + * ossl_crypto_condvar_wait_timeout needs to use real time for the + * deadline + */ + deadline = ossl_time_add(ossl_time_subtract(deadline, + qta->now_cb(qta->now_cb_arg)), + ossl_time_now()); + } + ossl_crypto_condvar_wait_timeout(qta->cv, m, deadline); /* * We have now been woken up. This can be for one of the following @@ -56,7 +69,9 @@ static unsigned int assist_thread_main(void *arg) } int ossl_quic_thread_assist_init_start(QUIC_THREAD_ASSIST *qta, - QUIC_CHANNEL *ch) + QUIC_CHANNEL *ch, + OSSL_TIME (*now_cb)(void *arg), + void *now_cb_arg) { CRYPTO_MUTEX *mutex = ossl_quic_channel_get_mutex(ch); @@ -66,6 +81,8 @@ int ossl_quic_thread_assist_init_start(QUIC_THREAD_ASSIST *qta, qta->ch = ch; qta->teardown = 0; qta->joined = 0; + qta->now_cb = now_cb; + qta->now_cb_arg = now_cb_arg; qta->cv = ossl_crypto_condvar_new(); if (qta->cv == NULL)