asan: print_vms_time signed integer overflow
authorAlan Modra <amodra@gmail.com>
Thu, 24 Dec 2020 05:41:03 +0000 (16:11 +1030)
committerAlan Modra <amodra@gmail.com>
Thu, 24 Dec 2020 12:28:14 +0000 (22:58 +1030)
I really don't think anyone cares about underflow of vms time values,
but the potential segfault on a gmtime failure is worth fixing.

* readelf.c (INT64_MIN): Define if not already defined.
(print_vms_time): Catch 64-bit overflow when converting from
vms time to posix time.  Don't segfault if gmtime returns NULL.

binutils/ChangeLog
binutils/readelf.c

index 298c28c7e678524d3870e688d4eadda5eceb54dc..3626fd83972ba134a0a0731aedb024c3ac87bae3 100644 (file)
@@ -1,3 +1,9 @@
+2020-12-24  Alan Modra  <amodra@gmail.com>
+
+       * readelf.c (INT64_MIN): Define if not already defined.
+       (print_vms_time): Catch 64-bit overflow when converting from
+       vms time to posix time.  Don't segfault if gmtime returns NULL.
+
 2020-12-23  H.J. Lu  <hongjiu.lu@intel.com>
 
        * NEWS: Mention LAM_U48 and LAM_U57 support.
index 46fd87a974a5e9e84fda5ec8a8a72e9ea681e609..3e3ac2f71d4f52e737949c620d9e38386bc83627 100644 (file)
@@ -9886,20 +9886,29 @@ dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
 
 #define VMS_EPOCH_OFFSET 35067168000000000LL
 #define VMS_GRANULARITY_FACTOR 10000000
+#ifndef INT64_MIN
+#define INT64_MIN (-9223372036854775807LL - 1)
+#endif
 
 /* Display a VMS time in a human readable format.  */
 
 static void
 print_vms_time (bfd_int64_t vmstime)
 {
-  struct tm *tm;
+  struct tm *tm = NULL;
   time_t unxtime;
 
-  unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
-  tm = gmtime (&unxtime);
-  printf ("%04u-%02u-%02uT%02u:%02u:%02u",
-          tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
-          tm->tm_hour, tm->tm_min, tm->tm_sec);
+  if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
+    {
+      vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
+      unxtime = vmstime;
+      if (unxtime == vmstime)
+       tm = gmtime (&unxtime);
+    }
+  if (tm != NULL)
+    printf ("%04u-%02u-%02uT%02u:%02u:%02u",
+           tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+           tm->tm_hour, tm->tm_min, tm->tm_sec);
 }
 #endif /* BFD64 */