On Thu, Oct 26 2017, Steffan Karger <steffan.kar...@fox-it.com> wrote:
> Hi,
>
> Sorry for being late to respond.
>
> On 18-10-17 20:36, Jeremie Courreges-Anglas wrote:
>> - there are other places when a time_t is printed in openvpn.  Usually
>>   it is cast to (int), which is not a nice thing to do if you plan to
>>   support dates after 2038.
>> 
>>   I also stumbled upon this in src/openvpn/common.h
>> 
>>   /*
>>    * Printf formats for special types
>>    */
>>   #ifdef _WIN64
>>   #define ptr_format              "0x%I64x"
>>   #else
>>   #define ptr_format              "0x%08lx"
>>   #endif
>>   #define time_format             "%lu"
>>   #define fragment_header_format  "0x%08x"
>>   
>>   /* these are used to cast the arguments
>>    * and MUST match the formats above */
>>   typedef unsigned long time_type;
>>   #ifdef _WIN64
>>   typedef unsigned long long ptr_type;
>>   #else
>>   typedef unsigned long ptr_type;
>>   #endif
>> 
>>   time_format and time_type are indeed used in a few places where
>>   a time_t is printed.  Technically, "unsigned long" suffers from the
>>   same problem as "long" on platforms with a 32 bits "long", pushing the
>>   limit to 2106 instead of 2038.
>> 
>>   I would suggest using "long long" here too, but do you folks think
>>   that the whole "time_format/time_type" indirection makes sense?
>>   After all, those are currently the same on all platforms.
>> 
>>   I have a diff to fix places in src/openvpn where time_t variables are
>>   cast to (int), but it kinda depends on the approach you folks prefer
>>   to use.
>
> Not sure about the other devs, but I think we should get rid of this
> indirection.  Someone who forgets to cast to long long will likely also
> not use the time_format define.  Better be consistent in casting to long
> long and printing using %lld (which is obviously correct for a long
> long).  Patch is definitely welcome.

ok, thanks for confirming.

>>>> While we are at it, note that tv.tv_usec, per POSIX, is a SIGNED integer
>>>> type capable of representing numbers in the range [-1; 1,000,000] so
>>>> casting tv_usec to unsigned long without checking if it's -1 is
>>>> technically wrong, although I'd be surprised to see gettimeofday()
>>>> return a negative tv_usec - but UINT_MAX or ULONG_MAX likewise.
>>>
>>> It makes sense to respect the fact that suseconds_t can store a negative
>>> value.  But then the same can be said about time_t (since its signedness
>>> is not defined by posix).
>> 
>> I guess it makes sense to also choose a generic way to print
>> suseconds_t, whose size isn't defined by posix either, and deal with
>> both types at once.  I would suggest using %ld and a cast to (long), as
>> this is the underlying type on at least OpenBSD and Linux.
>
> Sounds good to me.

Then here's the patch.

Notes:
- (hopefully) all time_t values are printed with %lld/(long long).
  For suseconds_t, use %ld and (long).  The patch is only about fixing
  printf-like format strings, it does not attempt to fix potential
  2038-related overflows in the code.
- built-checked with clang.  Sometimes the code was hidden by
  #ifdefs, I tweaked those and added a bunch of "#error foo"  to make
  sure that the modified code was actually built.  mbedtls build also
  tested.
- packet_id_interactive_test() doesn't build, and uses sscanf(%lu) to
  parse a time_t.  Could fix this in another diff and convert to
  %lld/long long.
- looks like multi.c and options.c could use a setenv_long_long()
  function, instead of using setenv_unsigned().

Works well in my client-side tests.

From 6aa57eed8692f9790f5c6ad68087f849a6cf9633 Mon Sep 17 00:00:00 2001
From: Jeremie Courreges-Anglas <j...@wxcvbn.org>
Date: Thu, 26 Oct 2017 11:40:05 +0200
Subject: [PATCH] Print time_t as long long and suseconds_t as long

As per previous commit, this is a simple solution to cope with the
various sizes of time_t on different archs, including those that use 64
bits time_t on ILP32 archs to cope with y2038.

Also:
- convert the time_type/time_format abstraction that used unsigned long
  to inlined long long code
- print suseconds_t as a long, which appears to be the underlying type
  on most Unix systems around

Signed-off-by: Jeremie Courreges-Anglas <j...@wxcvbn.org>
---
 src/openvpn/common.h      |  2 --
 src/openvpn/error.c       |  4 ++--
 src/openvpn/event.c       | 10 +++++-----
 src/openvpn/forward.c     |  2 +-
 src/openvpn/multi.c       |  6 +++---
 src/openvpn/otime.c       | 18 +++++++++---------
 src/openvpn/packet_id.c   | 16 ++++++++--------
 src/openvpn/reliable.c    |  4 ++--
 src/openvpn/shaper.c      |  4 ++--
 src/openvpn/shaper.h      |  8 ++++----
 src/openvpn/ssl_openssl.c |  8 ++++----
 11 files changed, 40 insertions(+), 42 deletions(-)

diff --git a/src/openvpn/common.h b/src/openvpn/common.h
index bb08c01f..4ea3938d 100644
--- a/src/openvpn/common.h
+++ b/src/openvpn/common.h
@@ -57,12 +57,10 @@ typedef int interval_t;
 #else
 #define ptr_format              "0x%08lx"
 #endif
-#define time_format             "%lu"
 #define fragment_header_format  "0x%08x"
 
 /* these are used to cast the arguments
  * and MUST match the formats above */
-typedef unsigned long time_type;
 #ifdef _WIN64
 typedef unsigned long long ptr_type;
 #else
diff --git a/src/openvpn/error.c b/src/openvpn/error.c
index 7b46c5ec..26455455 100644
--- a/src/openvpn/error.c
+++ b/src/openvpn/error.c
@@ -342,9 +342,9 @@ x_msg_va(const unsigned int flags, const char *format, va_list arglist)
                 struct timeval tv;
                 gettimeofday(&tv, NULL);
 
-                fprintf(fp, "%lld.%06lu %x %s%s%s%s",
+                fprintf(fp, "%lld.%06ld %x %s%s%s%s",
                         (long long)tv.tv_sec,
-                        (unsigned long)tv.tv_usec,
+                        (long)tv.tv_usec,
                         flags,
                         prefix,
                         prefix_sep,
diff --git a/src/openvpn/event.c b/src/openvpn/event.c
index d1230704..2fb112b8 100644
--- a/src/openvpn/event.c
+++ b/src/openvpn/event.c
@@ -1041,10 +1041,10 @@ se_wait_fast(struct event_set *es, const struct timeval *tv, struct event_set_re
     struct timeval tv_tmp = *tv;
     int stat;
 
-    dmsg(D_EVENT_WAIT, "SE_WAIT_FAST maxfd=%d tv=%d/%d",
+    dmsg(D_EVENT_WAIT, "SE_WAIT_FAST maxfd=%d tv=%lld/%ld",
          ses->maxfd,
-         (int)tv_tmp.tv_sec,
-         (int)tv_tmp.tv_usec);
+         (long long)tv_tmp.tv_sec,
+         (long)tv_tmp.tv_usec);
 
     stat = select(ses->maxfd + 1, &ses->readfds, &ses->writefds, NULL, &tv_tmp);
 
@@ -1065,8 +1065,8 @@ se_wait_scalable(struct event_set *es, const struct timeval *tv, struct event_se
     fd_set write = ses->writefds;
     int stat;
 
-    dmsg(D_EVENT_WAIT, "SE_WAIT_SCALEABLE maxfd=%d tv=%d/%d",
-         ses->maxfd, (int)tv_tmp.tv_sec, (int)tv_tmp.tv_usec);
+    dmsg(D_EVENT_WAIT, "SE_WAIT_SCALEABLE maxfd=%d tv=%lld/%ld",
+         ses->maxfd, (long long)tv_tmp.tv_sec, (long)tv_tmp.tv_usec);
 
     stat = select(ses->maxfd + 1, &read, &write, NULL, &tv_tmp);
 
diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c
index 6cc59383..a91a8d9a 100644
--- a/src/openvpn/forward.c
+++ b/src/openvpn/forward.c
@@ -618,7 +618,7 @@ check_coarse_timers_dowork(struct context *c)
     process_coarse_timers(c);
     c->c2.coarse_timer_wakeup = now + c->c2.timeval.tv_sec;
 
-    dmsg(D_INTERVAL, "TIMER: coarse timer wakeup %d seconds", (int) c->c2.timeval.tv_sec);
+    dmsg(D_INTERVAL, "TIMER: coarse timer wakeup %lld seconds", (long long)c->c2.timeval.tv_sec);
 
     /* Is the coarse timeout NOT the earliest one? */
     if (c->c2.timeval.tv_sec > save.tv_sec)
diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c
index c798c438..4545bce1 100644
--- a/src/openvpn/multi.c
+++ b/src/openvpn/multi.c
@@ -2388,14 +2388,14 @@ multi_process_post(struct multi_context *m, struct multi_instance *mi, const uns
         multi_set_pending(m, ANY_OUT(&mi->context) ? mi : NULL);
 
 #ifdef MULTI_DEBUG_EVENT_LOOP
-        printf("POST %s[%d] to=%d lo=%d/%d w=%d/%d\n",
+        printf("POST %s[%d] to=%d lo=%d/%d w=%lld/%ld\n",
                id(mi),
                (int) (mi == m->pending),
                mi ? mi->context.c2.to_tun.len : -1,
                mi ? mi->context.c2.to_link.len : -1,
                (mi && mi->context.c2.fragment) ? mi->context.c2.fragment->outgoing.len : -1,
-               (int)mi->context.c2.timeval.tv_sec,
-               (int)mi->context.c2.timeval.tv_usec);
+               (long long)mi->context.c2.timeval.tv_sec,
+               (long)mi->context.c2.timeval.tv_usec);
 #endif
     }
 
diff --git a/src/openvpn/otime.c b/src/openvpn/otime.c
index 3e576cc0..d741ae07 100644
--- a/src/openvpn/otime.c
+++ b/src/openvpn/otime.c
@@ -88,9 +88,9 @@ const char *
 tv_string(const struct timeval *tv, struct gc_arena *gc)
 {
     struct buffer out = alloc_buf_gc(64, gc);
-    buf_printf(&out, "[%d/%d]",
-               (int) tv->tv_sec,
-               (int )tv->tv_usec);
+    buf_printf(&out, "[%lld/%ld]",
+               (long long)tv->tv_sec,
+               (long)tv->tv_usec);
     return BSTR(&out);
 }
 
@@ -103,7 +103,7 @@ const char *
 tv_string_abs(const struct timeval *tv, struct gc_arena *gc)
 {
     return time_string((time_t) tv->tv_sec,
-                       (int) tv->tv_usec,
+                       (long) tv->tv_usec,
                        true,
                        gc);
 }
@@ -132,7 +132,7 @@ time_string(time_t t, int usec, bool show_usec, struct gc_arena *gc)
 
     if (show_usec && tv.tv_usec)
     {
-        buf_printf(&out, " us=%d", (int)tv.tv_usec);
+        buf_printf(&out, " us=%ld", (long)tv.tv_usec);
     }
 
     return BSTR(&out);
@@ -198,10 +198,10 @@ time_test(void)
         t = time(NULL);
         gettimeofday(&tv, NULL);
 #if 1
-        msg(M_INFO, "t=%u s=%u us=%u",
-            (unsigned int)t,
-            (unsigned int)tv.tv_sec,
-            (unsigned int)tv.tv_usec);
+        msg(M_INFO, "t=%lld s=%lld us=%ld",
+            (long long)t,
+            (long long)tv.tv_sec,
+            (long)tv.tv_usec);
 #endif
     }
 }
diff --git a/src/openvpn/packet_id.c b/src/openvpn/packet_id.c
index a3ff5722..4e0e9868 100644
--- a/src/openvpn/packet_id.c
+++ b/src/openvpn/packet_id.c
@@ -608,14 +608,14 @@ packet_id_debug_print(int msglevel,
         }
         buf_printf(&out, "%c", c);
     }
-    buf_printf(&out, "] " time_format ":" packet_id_format, (time_type)p->time, (packet_id_print_type)p->id);
+    buf_printf(&out, "] %lld:" packet_id_format, (long long)p->time, (packet_id_print_type)p->id);
     if (pin)
     {
-        buf_printf(&out, " " time_format ":" packet_id_format, (time_type)pin->time, (packet_id_print_type)pin->id);
+        buf_printf(&out, " %lld:" packet_id_format, (long long)pin->time, (packet_id_print_type)pin->id);
     }
 
-    buf_printf(&out, " t=" time_format "[%d]",
-               (time_type)prev_now,
+    buf_printf(&out, " t=%lld[%d]",
+               (long long)prev_now,
                (int)(prev_now - tv.tv_sec));
 
     buf_printf(&out, " r=[%d,%d,%d,%d,%d]",
@@ -668,8 +668,8 @@ packet_id_interactive_test(void)
         {
             packet_id_reap_test(&pid.rec);
             test = packet_id_test(&pid.rec, &pin);
-            printf("packet_id_test (" time_format ", " packet_id_format ") returned %d\n",
-                   (time_type)pin.time,
+            printf("packet_id_test (%lld, " packet_id_format ") returned %d\n",
+                   (long long)pin.time,
                    (packet_id_print_type)pin.id,
                    test);
             if (test)
@@ -681,8 +681,8 @@ packet_id_interactive_test(void)
         {
             long_form = (count < 20);
             packet_id_alloc_outgoing(&pid.send, &pin, long_form);
-            printf("(" time_format "(" packet_id_format "), %d)\n",
-                   (time_type)pin.time,
+            printf("(%lld(" packet_id_format "), %d)\n",
+                   (long long)pin.time,
                    (packet_id_print_type)pin.id,
                    long_form);
             if (pid.send.id == 10)
diff --git a/src/openvpn/reliable.c b/src/openvpn/reliable.c
index 93541a9d..bfd8c247 100644
--- a/src/openvpn/reliable.c
+++ b/src/openvpn/reliable.c
@@ -788,14 +788,14 @@ reliable_debug_print(const struct reliable *rel, char *desc)
     printf("********* struct reliable %s\n", desc);
     printf("  initial_timeout=%d\n", (int)rel->initial_timeout);
     printf("  packet_id=" packet_id_format "\n", rel->packet_id);
-    printf("  now=" time_format "\n", now);
+    printf("  now=%lld\n", (long long)now);
     for (i = 0; i < rel->size; ++i)
     {
         const struct reliable_entry *e = &rel->array[i];
         if (e->active)
         {
             printf("  %d: packet_id=" packet_id_format " len=%d", i, e->packet_id, e->buf.len);
-            printf(" next_try=" time_format, e->next_try);
+            printf(" next_try=%lld", (long long)e->next_try);
             printf("\n");
         }
     }
diff --git a/src/openvpn/shaper.c b/src/openvpn/shaper.c
index 19dd54d0..de2da6db 100644
--- a/src/openvpn/shaper.c
+++ b/src/openvpn/shaper.c
@@ -76,8 +76,8 @@ shaper_soonest_event(struct timeval *tv, int delay)
         }
     }
 #ifdef SHAPER_DEBUG
-    dmsg(D_SHAPER_DEBUG, "SHAPER shaper_soonest_event sec=%d usec=%d ret=%d",
-         (int)tv->tv_sec, (int)tv->tv_usec, (int)ret);
+    dmsg(D_SHAPER_DEBUG, "SHAPER shaper_soonest_event sec=%lld usec=%ld ret=%d",
+         (long long)tv->tv_sec, (long)tv->tv_usec, (int)ret);
 #endif
     return ret;
 }
diff --git a/src/openvpn/shaper.h b/src/openvpn/shaper.h
index 6fac16d5..34f316fd 100644
--- a/src/openvpn/shaper.h
+++ b/src/openvpn/shaper.h
@@ -147,11 +147,11 @@ shaper_wrote_bytes(struct shaper *s, int nbytes)
         tv_add(&s->wakeup, &tv);
 
 #ifdef SHAPER_DEBUG
-        dmsg(D_SHAPER_DEBUG, "SHAPER shaper_wrote_bytes bytes=%d delay=%d sec=%d usec=%d",
+        dmsg(D_SHAPER_DEBUG, "SHAPER shaper_wrote_bytes bytes=%d delay=%ld sec=%lld usec=%ld",
              nbytes,
-             (int)tv.tv_usec,
-             (int)s->wakeup.tv_sec,
-             (int)s->wakeup.tv_usec);
+             (long)tv.tv_usec,
+             (long long)s->wakeup.tv_sec,
+             (long)s->wakeup.tv_usec);
 #endif
     }
 }
diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index 92a662b5..0bfb6939 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -1363,8 +1363,8 @@ bio_debug_data(const char *mode, BIO *bio, const uint8_t *buf, int len, const ch
     if (len > 0)
     {
         open_biofp();
-        fprintf(biofp, "BIO_%s %s time=" time_format " bio=" ptr_format " len=%d data=%s\n",
-                mode, desc, time(NULL), (ptr_type)bio, len, format_hex(buf, len, 0, &gc));
+        fprintf(biofp, "BIO_%s %s time=%lld bio=" ptr_format " len=%d data=%s\n",
+                mode, desc, (long long)time(NULL), (ptr_type)bio, len, format_hex(buf, len, 0, &gc));
         fflush(biofp);
     }
     gc_free(&gc);
@@ -1374,8 +1374,8 @@ static void
 bio_debug_oc(const char *mode, BIO *bio)
 {
     open_biofp();
-    fprintf(biofp, "BIO %s time=" time_format " bio=" ptr_format "\n",
-            mode, time(NULL), (ptr_type)bio);
+    fprintf(biofp, "BIO %s time=%lld bio=" ptr_format "\n",
+            mode, (long long)time(NULL), (ptr_type)bio);
     fflush(biofp);
 }
 
-- 
2.14.2

-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Attachment: signature.asc
Description: PGP signature

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Openvpn-devel mailing list
Openvpn-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

Reply via email to