aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2020-12-24 16:11:03 +1030
committerAlan Modra <amodra@gmail.com>2020-12-24 22:58:14 +1030
commitdccc31dee37b559219708c8d0accc7d512d51c1f (patch)
treed8a715ea7756951b41d671733c521e668622e51f
parentde34d42812a0b978b278cd344abeaee7c71fa55c (diff)
downloadfsf-binutils-gdb-dccc31dee37b559219708c8d0accc7d512d51c1f.zip
fsf-binutils-gdb-dccc31dee37b559219708c8d0accc7d512d51c1f.tar.gz
fsf-binutils-gdb-dccc31dee37b559219708c8d0accc7d512d51c1f.tar.bz2
asan: print_vms_time signed integer overflow
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.
-rw-r--r--binutils/ChangeLog6
-rw-r--r--binutils/readelf.c21
2 files changed, 21 insertions, 6 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 298c28c..3626fd8 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -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.
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 46fd87a..3e3ac2f7 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -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 */