]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Avoid overflow in wakeup time computation
authorSelva Nair <selva.nair@gmail.com>
Tue, 6 Mar 2018 06:09:28 +0000 (01:09 -0500)
committerGert Doering <gert@greenie.muc.de>
Sat, 24 Mar 2018 16:42:12 +0000 (17:42 +0100)
Time interval arithmetic can overflow especially when user
defined intervals are involved. E.g., see Trac #922.

Avoid this by reordering the arithmetic operation in
event_timeout_trigger(). Also avoid unnecessary casting of time
variable to int.

Time until wakeup is now calculated like:

time_t wakeup = (last - now) + delay

Here delay is of type int, but is +ve by construction. Time backtrack
protection in OpenVPN ensures (last - now) <= 0. Then the above
expression cannot overflow (provided time_t is at least as large
as int).

A similar expression in interval.h is also changed.

(This patch grew out of patch 168 by Steffan Karger.)

Trac: #922

Signed-off-by: Selva Nair <selva.nair@gmail.com>
Acked-by: Steffan Karger <steffan.karger@fox-it.com>
Message-Id: <1520316568-8983-1-git-send-email-selva.nair@gmail.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg16634.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
(cherry picked from commit f158c0e1df13ae1b697cdc7f189ddd1575a0c1aa)

src/openvpn/interval.c
src/openvpn/interval.h

index 00ee62717dc33f4775443cccd2a9a9509936c6e1..b728560b3feb7b0ac0d37ad699c5d8e2cd7d7de4 100644 (file)
@@ -51,11 +51,12 @@ event_timeout_trigger(struct event_timeout *et,
 
     if (et->defined)
     {
-        int wakeup = (int) et->last + et->n - local_now;
+        time_t wakeup = et->last - local_now + et->n;
         if (wakeup <= 0)
         {
 #if INTERVAL_DEBUG
-            dmsg(D_INTERVAL, "EVENT event_timeout_trigger (%d) etcr=%d", et->n, et_const_retry);
+            dmsg(D_INTERVAL, "EVENT event_timeout_trigger (%d) etcr=%d", et->n,
+                 et_const_retry);
 #endif
             if (et_const_retry < 0)
             {
@@ -72,7 +73,8 @@ event_timeout_trigger(struct event_timeout *et,
         if (tv && wakeup < tv->tv_sec)
         {
 #if INTERVAL_DEBUG
-            dmsg(D_INTERVAL, "EVENT event_timeout_wakeup (%d/%d) etcr=%d", wakeup, et->n, et_const_retry);
+            dmsg(D_INTERVAL, "EVENT event_timeout_wakeup (%d/%d) etcr=%d",
+                 (int) wakeup, et->n, et_const_retry);
 #endif
             tv->tv_sec = wakeup;
             tv->tv_usec = 0;
index 826a08ba77ab5422b892d69ee2f2d53bcf32d81f..5623f3aed2e225adb2cdd22a39c3b89b095d4522 100644 (file)
@@ -196,7 +196,7 @@ event_timeout_modify_wakeup(struct event_timeout *et, interval_t n)
 static inline interval_t
 event_timeout_remaining(struct event_timeout *et)
 {
-    return (int) et->last + et->n - now;
+    return (interval_t) (et->last - now + et->n);
 }
 
 /*