summaryrefslogtreecommitdiff
path: root/scp.c
diff options
context:
space:
mode:
authormillert@openbsd.org <millert@openbsd.org>2017-04-28 03:21:12 +0000
committerDamien Miller <djm@mindrot.org>2017-04-28 13:26:37 +1000
commit066437187e16dcafcbc19f9402ef0e6575899b1d (patch)
tree2ca1d42349e905816c641b12e606567831deebb7 /scp.c
parent68d3a2a059183ebd83b15e54984ffaced04d2742 (diff)
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.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/scp.c b/scp.c
index 45541af00..3de743e3a 100644
--- a/scp.c
+++ b/scp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: scp.c,v 1.188 2017/04/27 11:53:12 millert Exp $ */ 1/* $OpenBSD: scp.c,v 1.189 2017/04/28 03:21:12 millert Exp $ */
2/* 2/*
3 * scp - secure remote copy. This is basically patched BSD rcp which 3 * scp - secure remote copy. This is basically patched BSD rcp which
4 * uses ssh to do the data transfer (instead of using rcmd). 4 * uses ssh to do the data transfer (instead of using rcmd).
@@ -99,6 +99,7 @@
99#include <pwd.h> 99#include <pwd.h>
100#include <signal.h> 100#include <signal.h>
101#include <stdarg.h> 101#include <stdarg.h>
102#include <stdint.h>
102#include <stdio.h> 103#include <stdio.h>
103#include <stdlib.h> 104#include <stdlib.h>
104#include <string.h> 105#include <string.h>
@@ -915,6 +916,11 @@ rsource(char *name, struct stat *statp)
915 (void) response(); 916 (void) response();
916} 917}
917 918
919#define TYPE_OVERFLOW(type, val) \
920 ((sizeof(type) == 4 && (val) > INT32_MAX) || \
921 (sizeof(type) == 8 && (val) > INT64_MAX) || \
922 (sizeof(type) != 4 && sizeof(type) != 8))
923
918void 924void
919sink(int argc, char **argv) 925sink(int argc, char **argv)
920{ 926{
@@ -938,6 +944,9 @@ sink(int argc, char **argv)
938#define mtime tv[1] 944#define mtime tv[1]
939#define SCREWUP(str) { why = str; goto screwup; } 945#define SCREWUP(str) { why = str; goto screwup; }
940 946
947 if (TYPE_OVERFLOW(time_t, 0) || TYPE_OVERFLOW(off_t, 0))
948 SCREWUP("Unexpected off_t/time_t size");
949
941 setimes = targisdir = 0; 950 setimes = targisdir = 0;
942 mask = umask(0); 951 mask = umask(0);
943 if (!pflag) 952 if (!pflag)
@@ -996,8 +1005,7 @@ sink(int argc, char **argv)
996 ull = strtoull(cp, &cp, 10); 1005 ull = strtoull(cp, &cp, 10);
997 if (!cp || *cp++ != ' ') 1006 if (!cp || *cp++ != ' ')
998 SCREWUP("mtime.sec not delimited"); 1007 SCREWUP("mtime.sec not delimited");
999 if ((time_t)ull < 0 || 1008 if (TYPE_OVERFLOW(time_t, ull))
1000 (unsigned long long)(time_t)ull != ull)
1001 setimes = 0; /* out of range */ 1009 setimes = 0; /* out of range */
1002 mtime.tv_sec = ull; 1010 mtime.tv_sec = ull;
1003 mtime.tv_usec = strtol(cp, &cp, 10); 1011 mtime.tv_usec = strtol(cp, &cp, 10);
@@ -1009,8 +1017,7 @@ sink(int argc, char **argv)
1009 ull = strtoull(cp, &cp, 10); 1017 ull = strtoull(cp, &cp, 10);
1010 if (!cp || *cp++ != ' ') 1018 if (!cp || *cp++ != ' ')
1011 SCREWUP("atime.sec not delimited"); 1019 SCREWUP("atime.sec not delimited");
1012 if ((time_t)ull < 0 || 1020 if (TYPE_OVERFLOW(time_t, ull))
1013 (unsigned long long)(time_t)ull != ull)
1014 setimes = 0; /* out of range */ 1021 setimes = 0; /* out of range */
1015 atime.tv_sec = ull; 1022 atime.tv_sec = ull;
1016 atime.tv_usec = strtol(cp, &cp, 10); 1023 atime.tv_usec = strtol(cp, &cp, 10);
@@ -1048,7 +1055,7 @@ sink(int argc, char **argv)
1048 ull = strtoull(cp, &cp, 10); 1055 ull = strtoull(cp, &cp, 10);
1049 if (!cp || *cp++ != ' ') 1056 if (!cp || *cp++ != ' ')
1050 SCREWUP("size not delimited"); 1057 SCREWUP("size not delimited");
1051 if ((off_t)ull < 0 || (unsigned long long)(off_t)ull != ull) 1058 if (TYPE_OVERFLOW(off_t, ull))
1052 SCREWUP("size out of range"); 1059 SCREWUP("size out of range");
1053 size = (off_t)ull; 1060 size = (off_t)ull;
1054 1061