upstream commit

Avoid relying on implementation-specific behavior when
detecting whether the timestamp or file size overflowed.  If time_t and off_t
are not either 32-bit or 64-bit scp will exit with an error. OK djm@

Upstream-ID: f31caae73ddab6df496b7bbbf7da431e267ad135
diff --git a/scp.c b/scp.c
index 45541af..3de743e 100644
--- a/scp.c
+++ b/scp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scp.c,v 1.188 2017/04/27 11:53:12 millert Exp $ */
+/* $OpenBSD: scp.c,v 1.189 2017/04/28 03:21:12 millert Exp $ */
 /*
  * scp - secure remote copy.  This is basically patched BSD rcp which
  * uses ssh to do the data transfer (instead of using rcmd).
@@ -99,6 +99,7 @@
 #include <pwd.h>
 #include <signal.h>
 #include <stdarg.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -915,6 +916,11 @@
 	(void) response();
 }
 
+#define TYPE_OVERFLOW(type, val) \
+	((sizeof(type) == 4 && (val) > INT32_MAX) || \
+	 (sizeof(type) == 8 && (val) > INT64_MAX) || \
+	 (sizeof(type) != 4 && sizeof(type) != 8))
+
 void
 sink(int argc, char **argv)
 {
@@ -938,6 +944,9 @@
 #define	mtime	tv[1]
 #define	SCREWUP(str)	{ why = str; goto screwup; }
 
+	if (TYPE_OVERFLOW(time_t, 0) || TYPE_OVERFLOW(off_t, 0))
+		SCREWUP("Unexpected off_t/time_t size");
+
 	setimes = targisdir = 0;
 	mask = umask(0);
 	if (!pflag)
@@ -996,8 +1005,7 @@
 			ull = strtoull(cp, &cp, 10);
 			if (!cp || *cp++ != ' ')
 				SCREWUP("mtime.sec not delimited");
-			if ((time_t)ull < 0 ||
-			    (unsigned long long)(time_t)ull != ull)
+			if (TYPE_OVERFLOW(time_t, ull))
 				setimes = 0;	/* out of range */
 			mtime.tv_sec = ull;
 			mtime.tv_usec = strtol(cp, &cp, 10);
@@ -1009,8 +1017,7 @@
 			ull = strtoull(cp, &cp, 10);
 			if (!cp || *cp++ != ' ')
 				SCREWUP("atime.sec not delimited");
-			if ((time_t)ull < 0 ||
-			    (unsigned long long)(time_t)ull != ull)
+			if (TYPE_OVERFLOW(time_t, ull))
 				setimes = 0;	/* out of range */
 			atime.tv_sec = ull;
 			atime.tv_usec = strtol(cp, &cp, 10);
@@ -1048,7 +1055,7 @@
 		ull = strtoull(cp, &cp, 10);
 		if (!cp || *cp++ != ' ')
 			SCREWUP("size not delimited");
-		if ((off_t)ull < 0 || (unsigned long long)(off_t)ull != ull)
+		if (TYPE_OVERFLOW(off_t, ull))
 			SCREWUP("size out of range");
 		size = (off_t)ull;