summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Mraz <tomas@openssl.org>2023-03-17 12:16:33 +0100
committerDr. David von Oheimb <dev@ddvo.net>2023-03-18 19:04:58 +0100
commitbea92b8c3d61960a2d06f8d342ef01d30a2fa195 (patch)
tree23efa92fd046409c1f670d4ff97f04c015cd6fe2
parent46ce0854db51e373ab6ed4982431349107cd9b6d (diff)
sleep.c: Limit the sleep time instead of sleeping for days or even years
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)
-rw-r--r--crypto/sleep.c44
-rw-r--r--doc/man3/OSSL_sleep.pod9
2 files changed, 19 insertions, 34 deletions
diff --git a/crypto/sleep.c b/crypto/sleep.c
index 1554d936cf..3eac44dd74 100644
--- a/crypto/sleep.c
+++ b/crypto/sleep.c
@@ -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)
diff --git a/doc/man3/OSSL_sleep.pod b/doc/man3/OSSL_sleep.pod
index 5264d2b569..896adb7f15 100644
--- a/doc/man3/OSSL_sleep.pod
+++ b/doc/man3/OSSL_sleep.pod
@@ -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