eloop: Fix integer overflow in long timeouts
If the os_time_t variable used for the expiration time (seconds) overflows when the registered timeout value is being added, assume that the event would happen after an infinite time, i.e., would not really happen in practice. This fixes issues with long key timeouts getting converted to immediate expiration due to the overflow.
This commit is contained in:
parent
9fc6aa9f95
commit
0fa0ad4e17
2 changed files with 24 additions and 0 deletions
|
@ -300,6 +300,7 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs,
|
||||||
void *eloop_data, void *user_data)
|
void *eloop_data, void *user_data)
|
||||||
{
|
{
|
||||||
struct eloop_timeout *timeout, *tmp;
|
struct eloop_timeout *timeout, *tmp;
|
||||||
|
os_time_t now_sec;
|
||||||
|
|
||||||
timeout = os_zalloc(sizeof(*timeout));
|
timeout = os_zalloc(sizeof(*timeout));
|
||||||
if (timeout == NULL)
|
if (timeout == NULL)
|
||||||
|
@ -308,7 +309,18 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs,
|
||||||
os_free(timeout);
|
os_free(timeout);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
now_sec = timeout->time.sec;
|
||||||
timeout->time.sec += secs;
|
timeout->time.sec += secs;
|
||||||
|
if (timeout->time.sec < now_sec) {
|
||||||
|
/*
|
||||||
|
* Integer overflow - assume long enough timeout to be assumed
|
||||||
|
* to be infinite, i.e., the timeout would never happen.
|
||||||
|
*/
|
||||||
|
wpa_printf(MSG_DEBUG, "ELOOP: Too long timeout (secs=%u) to "
|
||||||
|
"ever happen - ignore it", secs);
|
||||||
|
os_free(timeout);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
timeout->time.usec += usecs;
|
timeout->time.usec += usecs;
|
||||||
while (timeout->time.usec >= 1000000) {
|
while (timeout->time.usec >= 1000000) {
|
||||||
timeout->time.sec++;
|
timeout->time.sec++;
|
||||||
|
|
|
@ -243,12 +243,24 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs,
|
||||||
void *eloop_data, void *user_data)
|
void *eloop_data, void *user_data)
|
||||||
{
|
{
|
||||||
struct eloop_timeout *timeout, *tmp, *prev;
|
struct eloop_timeout *timeout, *tmp, *prev;
|
||||||
|
os_time_t now_sec;
|
||||||
|
|
||||||
timeout = os_malloc(sizeof(*timeout));
|
timeout = os_malloc(sizeof(*timeout));
|
||||||
if (timeout == NULL)
|
if (timeout == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
os_get_time(&timeout->time);
|
os_get_time(&timeout->time);
|
||||||
|
now_sec = timeout->time.sec;
|
||||||
timeout->time.sec += secs;
|
timeout->time.sec += secs;
|
||||||
|
if (timeout->time.sec < now_sec) {
|
||||||
|
/*
|
||||||
|
* Integer overflow - assume long enough timeout to be assumed
|
||||||
|
* to be infinite, i.e., the timeout would never happen.
|
||||||
|
*/
|
||||||
|
wpa_printf(MSG_DEBUG, "ELOOP: Too long timeout (secs=%u) to "
|
||||||
|
"ever happen - ignore it", secs);
|
||||||
|
os_free(timeout);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
timeout->time.usec += usecs;
|
timeout->time.usec += usecs;
|
||||||
while (timeout->time.usec >= 1000000) {
|
while (timeout->time.usec >= 1000000) {
|
||||||
timeout->time.sec++;
|
timeout->time.sec++;
|
||||||
|
|
Loading…
Reference in a new issue