From f711dfeffbad37dbf92be6e1de44579de054d16f Mon Sep 17 00:00:00 2001 From: millert Date: Fri, 28 Apr 2017 03:21:12 +0000 Subject: [PATCH] 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@ --- usr.bin/ssh/scp.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/usr.bin/ssh/scp.c b/usr.bin/ssh/scp.c index dcf68372544..f61b3dd29ef 100644 --- a/usr.bin/ssh/scp.c +++ b/usr.bin/ssh/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). @@ -86,6 +86,7 @@ #include #include #include +#include #include #include #include @@ -894,6 +895,11 @@ rsource(char *name, struct stat *statp) (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) { @@ -917,6 +923,9 @@ sink(int argc, char **argv) #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) @@ -975,8 +984,7 @@ sink(int argc, char **argv) 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); @@ -988,8 +996,7 @@ sink(int argc, char **argv) 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); @@ -1027,7 +1034,7 @@ sink(int argc, char **argv) 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; -- 2.20.1