]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
sleep.c: Limit the sleep time instead of sleeping for days or even years
authorTomas Mraz <tomas@openssl.org>
Fri, 17 Mar 2023 11:16:33 +0000 (12:16 +0100)
committerDr. David von Oheimb <dev@ddvo.net>
Sat, 18 Mar 2023 18:04:58 +0000 (19:04 +0100)
As the sleep() call is interruptible, it is not even a good idea to call
it in a loop if the caller uses some ridiculously large value as an
infinity just waiting for an interrupt.

Fixes #20524

Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Tom Cosgrove <tom.cosgrove@arm.com>
(Merged from https://github.com/openssl/openssl/pull/20533)

crypto/sleep.c
doc/man3/OSSL_sleep.pod

index 1554d936cfae060c0f3f12d2a9946b95be2a95a8..3eac44dd748a44bd1d22cc7322485ec4209a87bb 100644 (file)
@@ -46,27 +46,15 @@ void OSSL_sleep(uint64_t millis)
 {
     /*
      * Windows' Sleep() takes a DWORD argument, which is smaller than
-     * a uint64_t, so we need to split the two to shut the compiler up.
+     * a uint64_t, so we need to limit it to 49 days, which should be enough.
      */
-    DWORD dword_times;
-    DWORD i;
+    DWORD limited_millis = (DWORD)-1;
 
-    dword_times = (DWORD)(millis >> (8 * sizeof(DWORD)));
-    millis &= (DWORD)-1;
-    if (dword_times > 0) {
-        for (i = dword_times; i-- > 0;)
-            Sleep((DWORD)-1);
-        /*
-         * The loop above slept 1 millisec less on each iteration than it
-         * should, this compensates by sleeping as many milliseconds as there
-         * were iterations.  Yes, this is nit picky!
-         */
-        Sleep(dword_times);
-    }
-
-    /* Now, sleep the remaining milliseconds */
-    Sleep((DWORD)(millis));
+    if (millis < limited_millis)
+        limited_millis = (DWORD)millis;
+    Sleep(limited_millis);
 }
+
 #else
 /* Fallback to a busy wait */
 # include "internal/time.h"
@@ -75,22 +63,14 @@ static void ossl_sleep_secs(uint64_t secs)
 {
     /*
      * sleep() takes an unsigned int argument, which is smaller than
-     * a uint64_t, so it needs to be called in smaller increments.
+     * a uint64_t, so it needs to be limited to 136 years which
+     * should be enough even for Sleeping Beauty.
      */
-    unsigned int uint_times;
-    unsigned int i;
+    unsigned int limited_secs = UINT_MAX;
 
-    uint_times = (unsigned int)(secs >> (8 * sizeof(unsigned int)));
-    if (uint_times > 0) {
-        for (i = uint_times; i-- > 0;)
-            sleep((unsigned int)-1);
-        /*
-         * The loop above slept 1 second less on each iteration than it
-         * should, this compensates by sleeping as many seconds as there were
-         * iterations.  Yes, this is nit picky!
-         */
-        sleep(uint_times);
-    }
+    if (secs < limited_secs)
+        limited_secs = (unsigned int)secs;
+    sleep(limited_secs);
 }
 
 static void ossl_sleep_millis(uint64_t millis)
index 5264d2b569ecb8bbb68336ce24beceef1fd671ad..896adb7f1529559e3d988189e787b4cd395c6415 100644 (file)
@@ -14,8 +14,13 @@ OSSL_sleep - delay execution for a specified number of milliseconds
 
 OSSL_sleep() is a convenience function to delay execution of the calling
 thread for (at least) I<millis> milliseconds.  The delay is not guaranteed;
-it may be affected by system activity, by the time spent processing the call
-or by system timer granularity.
+it may be affected by system activity, by the time spent processing the call,
+limitation on the underlying system call parameter size or by system timer
+granularity.
+
+In particular on Windows the maximum amount of time it will sleep is
+49 days and on systems where the regular sleep(3) is used as the underlying
+system call the maximum sleep time is about 136 years.
 
 =head1 RETURN VALUES