Avoid races in tserver test code
authorHugo Landau <hlandau@openssl.org>
Wed, 22 Feb 2023 17:01:28 +0000 (17:01 +0000)
committerHugo Landau <hlandau@openssl.org>
Thu, 30 Mar 2023 10:14:09 +0000 (11:14 +0100)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20348)

test/quic_tserver_test.c

index eeb23b4b908180d3fc2fce287cb864ec0f01a3c0..e5391648a3a80077b772b741eb08fb279ae8f6cf 100644 (file)
@@ -19,6 +19,7 @@
 static const char msg1[] = "The quick brown fox jumped over the lazy dogs.";
 static char msg2[1024], msg3[1024];
 static OSSL_TIME fake_time;
+static CRYPTO_RWLOCK *fake_time_lock;
 
 static const char *certfile, *keyfile;
 
@@ -33,7 +34,15 @@ static unsigned char scratch_buf[2048];
 
 static OSSL_TIME fake_now(void *arg)
 {
-    return fake_time;
+    OSSL_TIME t;
+
+    if (!CRYPTO_THREAD_read_lock(fake_time_lock))
+        return ossl_time_zero();
+
+    t = fake_time;
+
+    CRYPTO_THREAD_unlock(fake_time_lock);
+    return t;
 }
 
 static OSSL_TIME real_now(void *arg)
@@ -286,9 +295,14 @@ static int do_test(int use_thread_assist, int use_fake_time, int use_inject)
         if (c_start_idle_test && !c_done_idle_test) {
             /* This is more than our default idle timeout of 30s. */
             if (idle_units_done < 600) {
+                if (!TEST_true(CRYPTO_THREAD_write_lock(fake_time_lock)))
+                    goto err;
                 fake_time = ossl_time_add(fake_time, ossl_ms2time(100));
+                CRYPTO_THREAD_unlock(fake_time_lock);
+
                 ++idle_units_done;
                 ossl_quic_conn_force_assist_thread_wake(c_ssl);
+                OSSL_sleep(1); /* Ensure CPU scheduling for test purposes */
             } else {
                 c_done_idle_test = 1;
             }
@@ -397,6 +411,9 @@ int setup_tests(void)
             || !TEST_ptr(keyfile = test_get_argument(1)))
         return 0;
 
+    if ((fake_time_lock = CRYPTO_THREAD_lock_new()) == NULL)
+        return 0;
+
     ADD_TEST(test_tserver_simple);
     ADD_TEST(test_tserver_thread);
     ADD_TEST(test_tserver_thread_fake_time);