libc: mktime signed overflow

issue #3289
This commit is contained in:
Sebastian Sumpf 2019-05-28 11:54:12 +02:00 committed by Christian Helmuth
parent 9f02151d0b
commit 4b72bbaa57
4 changed files with 78 additions and 2 deletions

View File

@ -1 +1 @@
15bedbc9f3adea283d1c036ef57448ebbdaa4cbc
12ac556f17580c447e7502e0485a662610f59c06

View File

@ -39,4 +39,4 @@ build_boot_image {
append qemu_args " -nographic "
run_genode_until "child .* exited with exit value 0.*\n" 13
run_genode_until "child .* exited with exit value 0.*\n" 30

View File

@ -0,0 +1,44 @@
diff --git a/src/lib/libc/contrib/tzcode/stdtime/localtime.c b/src/lib/libc/contrib/tzcode/stdtime/localtime.c
index 3c66924..05c01ae 100644
--- src/lib/libc/contrib/tzcode/stdtime/localtime.c
+++ src/lib/libc/contrib/tzcode/stdtime/localtime.c
@@ -1935,6 +1935,10 @@ time2sub(struct tm *const tmp,
lo *= 2;
hi = -(lo + 1);
}
+
+ lo = TIME_T_MIN;
+ hi = TIME_T_MAX;
+
for ( ; ; ) {
t = lo / 2 + hi / 2;
if (t < lo)
diff --git a/src/lib/libc/contrib/tzcode/stdtime/private.h b/src/lib/libc/contrib/tzcode/stdtime/private.h
index 354a78b..8300ba0 100644
--- src/lib/libc/contrib/tzcode/stdtime/private.h
+++ src/lib/libc/contrib/tzcode/stdtime/private.h
@@ -251,6 +251,24 @@ const char * scheck(const char * string, const char * format);
1 + TYPE_SIGNED(type))
#endif /* !defined INT_STRLEN_MAXIMUM */
+#define TWOS_COMPLEMENT(t) ((t) ~ (t) 0 < 0)
+
+/* Max and min values of the integer type T, of which only the bottom
+ B bits are used, and where the highest-order used bit is considered
+ to be a sign bit if T is signed. */
+#define MAXVAL(t, b) \
+ ((t) (((t) 1 << ((b) - 1 - TYPE_SIGNED(t))) \
+ - 1 + ((t) 1 << ((b) - 1 - TYPE_SIGNED(t)))))
+#define MINVAL(t, b) \
+ ((t) (TYPE_SIGNED(t) ? - TWOS_COMPLEMENT(t) - MAXVAL(t, b) : 0))
+
+/* The extreme time values, assuming no padding. */
+#define TIME_T_MIN_NO_PADDING MINVAL(time_t, TYPE_BIT(time_t))
+#define TIME_T_MAX_NO_PADDING MAXVAL(time_t, TYPE_BIT(time_t))
+
+# define TIME_T_MIN TIME_T_MIN_NO_PADDING
+# define TIME_T_MAX TIME_T_MAX_NO_PADDING
+
/*
** INITIALIZE(x)
*/

View File

@ -30,6 +30,9 @@ extern "C" {
#include <time.h>
#include <sys/random.h>
#include <sys/syscall.h>
#include <sys/limits.h>
#include <time.h>
#include <inttypes.h>
}
int main(int argc, char **argv)
@ -171,5 +174,34 @@ int main(int argc, char **argv)
printf("getentropy %llx\n", buf);
}
do {
struct tm tm { };
/* 2019-05-27 12:30 */
tm.tm_sec = 0;
tm.tm_min = 30;
tm.tm_hour = 12;
tm.tm_mday = 27;
tm.tm_mon = 4;
tm.tm_year = 119;
time_t t1 = mktime(&tm);
if (t1 == (time_t) -1) {
++error_count;
long long v1 = t1;
printf("Check mktime failed: %lld\n", v1);
break;
}
struct tm *tm_gmt = gmtime(&t1);
time_t t2 = mktime(tm_gmt);
if (t1 != t2) {
++error_count;
long long v1 = t1, v2 = t2;
printf("Check mktime failed: %lld != %lld\n", v1, v2);
break;
}
puts("Check mktime: success");
} while (0);
exit(error_count);
}