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)
This commit is contained in:
Tomas Mraz 2023-03-17 12:16:33 +01:00 committed by Dr. David von Oheimb
parent 46ce0854db
commit bea92b8c3d
2 changed files with 19 additions and 34 deletions

View 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)

View 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