]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
eloop: Fix integer overflow in long timeouts
authorJouni Malinen <jouni.malinen@atheros.com>
Thu, 27 Jan 2011 12:02:03 +0000 (14:02 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 6 Mar 2011 12:31:20 +0000 (14:31 +0200)
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.

src/utils/eloop.c
src/utils/eloop_win.c

index 4b615989c0bbb7a9fb73b01f745d9f37ac06d94e..b550c6323d6007a4b739bafefb2d4e67a23f4bac 100644 (file)
@@ -300,6 +300,7 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs,
                           void *eloop_data, void *user_data)
 {
        struct eloop_timeout *timeout, *tmp;
+       os_time_t now_sec;
 
        timeout = os_zalloc(sizeof(*timeout));
        if (timeout == NULL)
@@ -308,7 +309,18 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs,
                os_free(timeout);
                return -1;
        }
+       now_sec = timeout->time.sec;
        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;
        while (timeout->time.usec >= 1000000) {
                timeout->time.sec++;
index 94cc72d04c6b6fc06662221b0b82707f80b6b574..c726ece25de2381f48a7c602aa40b9a28b9adb32 100644 (file)
@@ -243,12 +243,24 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs,
                           void *eloop_data, void *user_data)
 {
        struct eloop_timeout *timeout, *tmp, *prev;
+       os_time_t now_sec;
 
        timeout = os_malloc(sizeof(*timeout));
        if (timeout == NULL)
                return -1;
        os_get_time(&timeout->time);
+       now_sec = timeout->time.sec;
        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;
        while (timeout->time.usec >= 1000000) {
                timeout->time.sec++;