diff options
author | millert@openbsd.org <millert@openbsd.org> | 2017-04-28 05:21:12 +0200 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2017-04-28 05:26:37 +0200 |
commit | 066437187e16dcafcbc19f9402ef0e6575899b1d (patch) | |
tree | 2ca1d42349e905816c641b12e606567831deebb7 /scp.c | |
parent | upstream commit (diff) | |
download | openssh-066437187e16dcafcbc19f9402ef0e6575899b1d.tar.xz openssh-066437187e16dcafcbc19f9402ef0e6575899b1d.zip |
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
Diffstat (limited to 'scp.c')
-rw-r--r-- | scp.c | 19 |
1 files changed, 13 insertions, 6 deletions
@@ -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 @@ 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) { @@ -938,6 +944,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) @@ -996,8 +1005,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); @@ -1009,8 +1017,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); @@ -1048,7 +1055,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; |