diff options
author | Tomas Mraz <tomas@openssl.org> | 2023-03-17 12:16:33 +0100 |
---|---|---|
committer | Dr. David von Oheimb <dev@ddvo.net> | 2023-03-18 19:04:58 +0100 |
commit | bea92b8c3d61960a2d06f8d342ef01d30a2fa195 (patch) | |
tree | 23efa92fd046409c1f670d4ff97f04c015cd6fe2 | |
parent | 46ce0854db51e373ab6ed4982431349107cd9b6d (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.c | 44 | ||||
-rw-r--r-- | doc/man3/OSSL_sleep.pod | 9 |
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 |