[Openswan dev] Problem and proposed bug fix to Openswan when the system's time jumps forward multiple decades

Antony Richards arichards at cybertec.com.au
Thu Aug 4 01:33:53 EDT 2011


Hi,

As requested by LetoTo I have forwarded my IRC message to email.


I came across a bug in Openswan.  The box starts up.  Openswan 
connects.  The date is set back to 1970, NTPD is started and sets the 
date to be 2011.

After this, the command "ipsec auto --status" blocks indefinitely.

Analysis (based on 2.4 and verified in 2.6) is that in 
timer.c:next_event(), the expression *evlist->ev_time - now()* is 
negative (ev_time is 40 years ago).  Hence next_event() returns 0, 
causing the event to be triggered.

But when handle_timer_event() is called, the expression *now() < 
ev->ev_time* evaluates to TRUE (due to long wrapping???), meaning that 
the event is not removed from the event list.

Looking at /server.c/, the code becomes stuck in the loop ... in 
/call_server()/  next_event() returns 0.  This then sets ndes to 0 (and 
osw_select() is NOT called).  But when handle_timer_event() is called, 
the function believes that there are no events to handle, so the event 
queue does not change.  So when call_server() loops it calls 
next_event() which returns 0 again.

This blocks the thread from calling the select() function to handle all 
the file descriptors. Hence *ipsec auto --status* never gets a reply to 
its request, and will block forever.  Likewise, all communications into 
Openswan never gets a reply.

A proposed solution (that I have tested successfully in version 2.4) is 
to change now() to use the systems uptime instead.  This solution also 
has the benefit that timing jitter is not introduced by people setting 
the time on a device or programs such as ntpd.

Let me know if you have any questions.


Thanks,
Antony.


*Proposed diff ...
*
diff --git a/lib/libopenswan/oswtime.c b/lib/libopenswan/oswtime.c
index 6440258..7e17529 100644
--- a/lib/libopenswan/oswtime.c
+++ b/lib/libopenswan/oswtime.c
@@ -22,6 +22,7 @@
  #include <unistd.h>
  #include <netinet/in.h>
  #include <arpa/inet.h>
+#include <sys/sysinfo.h>

  #include <openswan.h>

@@ -34,18 +35,18 @@
  time_t
  now(void)
  {
-    static time_t delta = 0
-       , last_time = 0;
-    time_t n = time(NULL);
+  /*
+   * Use uptime as it cannot jump unexpentantly,
+   * for example, when the time is changed forwards or backwards.
+   */
+    struct sysinfo info;

-    passert(n != (time_t)-1);
-    if (last_time > n)
+    if (sysinfo(&info) == 0)
      {
-       openswan_log("time moved backwards %ld seconds", 
(long)(last_time - n));
-       delta += last_time - n;
+      return (time_t)info.uptime;
      }
-    last_time = n;
-    return n + delta;
+    passert(0);
+    return 0;
  }

  /* Names of the months */


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.openswan.org/pipermail/dev/attachments/20110804/5eafb1ac/attachment.html 


More information about the Dev mailing list