From dccc31dee37b559219708c8d0accc7d512d51c1f Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 24 Dec 2020 16:11:03 +1030 Subject: 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. --- binutils/ChangeLog | 6 ++++++ binutils/readelf.c | 21 +++++++++++++++------ 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 + + * 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 * 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 */ -- cgit v1.1