Commit e0a65e5240 for openssl.org
commit e0a65e5240b4d69b1f7b168f9a84e10618b50082
Author: Nicky Mouha <nicky@mouha.be>
Date: Wed Oct 28 13:30:50 2026 -0400
test/dtlsssllistenertest.c: use mutex for accessing urxe_pending queue
The urxe_pending queue in DTLS_RX is protected by rx->mutex.
Add the mutex around the four remaining accesses
in idle_pending_state_cb(), redrive_idle_cb(),
test_dtls_listener_rx_queue_drops_oldest(),
and test_dtls_listener_flood_then_handshake_int().
These accesses occur in single-threaded tests, so mutexes
are not required. However, using the same queue locking
pattern in both the library code and the tests is good
practice and avoids Coverty alerts.
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Merge-date: Tue Nov 10 05:25:28 2026
Merged-from: https://github.com/openssl/openssl/pull/33439
diff --git a/test/dtlsssllistenertest.c b/test/dtlsssllistenertest.c
index 9b327f1fc6..c3cdfca811 100644
--- a/test/dtlsssllistenertest.c
+++ b/test/dtlsssllistenertest.c
@@ -6937,6 +6937,7 @@ static int test_dtls_listener_rx_queue_drops_oldest(void)
BIO_ADDR *client_addr = NULL;
BIO *client_bio;
SSL_CONNECTION *sc;
+ DTLS_RX *rx;
SSL_POLL_ITEM poll_item;
struct timeval poll_timeout;
size_t poll_result, queued, i;
@@ -6992,15 +6993,23 @@ static int test_dtls_listener_rx_queue_drops_oldest(void)
}
if (!TEST_ptr(sc = SSL_CONNECTION_FROM_SSL_ONLY(serverssl))
- || !TEST_ptr(sc->listener_rx))
+ || !TEST_ptr(rx = sc->listener_rx))
goto end;
- queued = ossl_list_urxe_num(&sc->listener_rx->urxe_pending);
+ /*
+ * This test is single-threaded, but a mutex lock follows the normal
+ * queue access pattern.
+ */
+ ossl_crypto_mutex_lock(rx->mutex);
+ queued = ossl_list_urxe_num(&rx->urxe_pending);
+ head = ossl_list_urxe_head(&rx->urxe_pending);
+ tail = ossl_list_urxe_tail(&rx->urxe_pending);
+ ossl_crypto_mutex_unlock(rx->mutex);
+
if (!TEST_size_t_eq(queued, cap))
goto end;
/* The oldest datagrams were evicted: only the newest cap ones remain. */
- if (!TEST_ptr(head = ossl_list_urxe_head(&sc->listener_rx->urxe_pending))
- || !TEST_ptr(tail = ossl_list_urxe_tail(&sc->listener_rx->urxe_pending)))
+ if (!TEST_ptr(head) || !TEST_ptr(tail))
goto end;
head_data = ossl_dgram_urxe_data(head);
tail_data = ossl_dgram_urxe_data(tail);
@@ -7392,6 +7401,7 @@ static int test_dtls_listener_flood_then_handshake_int(int version)
int server_fd = -1, client_fd = -1, client2_fd = -1;
DTLS_LISTENER *dl;
SSL_CONNECTION *sc;
+ DTLS_RX *rx;
unsigned char garbage[1200];
size_t queued, i;
int testresult = 0, k;
@@ -7443,9 +7453,15 @@ static int test_dtls_listener_flood_then_handshake_int(int version)
/* The receive queue is exactly at its cap, not at the flood size. */
if (!TEST_ptr(sc = SSL_CONNECTION_FROM_SSL_ONLY(serverssl))
- || !TEST_ptr(sc->listener_rx))
+ || !TEST_ptr(rx = sc->listener_rx))
goto end;
- queued = ossl_list_urxe_num(&sc->listener_rx->urxe_pending);
+ /*
+ * This test is single-threaded, but a mutex lock follows the normal
+ * queue access pattern.
+ */
+ ossl_crypto_mutex_lock(rx->mutex);
+ queued = ossl_list_urxe_num(&rx->urxe_pending);
+ ossl_crypto_mutex_unlock(rx->mutex);
if (!TEST_size_t_eq(queued, cap))
goto end;
@@ -7627,6 +7643,7 @@ static void idle_pending_state_cb(SSL *ssl, const BIO_ADDR *peer, void *arg)
{
IDLE_PENDING_STATE *st = arg;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl);
+ DTLS_RX *rx;
if (sc == NULL || sc->listener_rx == NULL) {
st->queued++;
@@ -7635,8 +7652,15 @@ static void idle_pending_state_cb(SSL *ssl, const BIO_ADDR *peer, void *arg)
if (sc->hello_retry_request == SSL_HRR_PENDING
|| sc->statem.hand_state == DTLS_ST_SW_HELLO_VERIFY_REQUEST)
st->retry_sent++;
- if (!ossl_list_urxe_is_empty(&sc->listener_rx->urxe_pending))
+ rx = sc->listener_rx;
+ /*
+ * This test is single-threaded, but a mutex lock follows the normal queue
+ * access pattern.
+ */
+ ossl_crypto_mutex_lock(rx->mutex);
+ if (!ossl_list_urxe_is_empty(&rx->urxe_pending))
st->queued++;
+ ossl_crypto_mutex_unlock(rx->mutex);
}
/*
@@ -7829,10 +7853,19 @@ static void redrive_ch_cb(int write_p, int version, int content_type,
static void redrive_idle_cb(SSL *ssl, const BIO_ADDR *peer, void *arg)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl);
+ DTLS_RX *rx;
- if (sc != NULL && sc->listener_idle && sc->listener_rx != NULL
- && ossl_list_urxe_is_empty(&sc->listener_rx->urxe_pending))
- (*(size_t *)arg)++;
+ if (sc != NULL && sc->listener_idle && sc->listener_rx != NULL) {
+ rx = sc->listener_rx;
+ /*
+ * This test is single-threaded, but a mutex lock follows the normal
+ * queue access pattern.
+ */
+ ossl_crypto_mutex_lock(rx->mutex);
+ if (ossl_list_urxe_is_empty(&rx->urxe_pending))
+ (*(size_t *)arg)++;
+ ossl_crypto_mutex_unlock(rx->mutex);
+ }
}
/* Are all |n| pending connections waiting for their peers? */