summaryrefslogtreecommitdiff
path: root/scp.c
diff options
context:
space:
mode:
Diffstat (limited to 'scp.c')
-rw-r--r--scp.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/scp.c b/scp.c
index 18c277201..12e3199d8 100644
--- a/scp.c
+++ b/scp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: scp.c,v 1.187 2016/09/12 01:22:38 deraadt Exp $ */ 1/* $OpenBSD: scp.c,v 1.192 2017/05/31 09:15:42 deraadt 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,9 @@
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#ifdef HAVE_STDINT_H
103#include <stdint.h>
104#endif
102#include <stdio.h> 105#include <stdio.h>
103#include <stdlib.h> 106#include <stdlib.h>
104#include <string.h> 107#include <string.h>
@@ -411,7 +414,11 @@ main(int argc, char **argv)
411 switch (ch) { 414 switch (ch) {
412 /* User-visible flags. */ 415 /* User-visible flags. */
413 case '1': 416 case '1':
417 fatal("SSH protocol v.1 is no longer supported");
418 break;
414 case '2': 419 case '2':
420 /* Ignored */
421 break;
415 case '4': 422 case '4':
416 case '6': 423 case '6':
417 case 'C': 424 case 'C':
@@ -923,6 +930,11 @@ rsource(char *name, struct stat *statp)
923 (void) response(); 930 (void) response();
924} 931}
925 932
933#define TYPE_OVERFLOW(type, val) \
934 ((sizeof(type) == 4 && (val) > INT32_MAX) || \
935 (sizeof(type) == 8 && (val) > INT64_MAX) || \
936 (sizeof(type) != 4 && sizeof(type) != 8))
937
926void 938void
927sink(int argc, char **argv) 939sink(int argc, char **argv)
928{ 940{
@@ -946,6 +958,9 @@ sink(int argc, char **argv)
946#define mtime tv[1] 958#define mtime tv[1]
947#define SCREWUP(str) { why = str; goto screwup; } 959#define SCREWUP(str) { why = str; goto screwup; }
948 960
961 if (TYPE_OVERFLOW(time_t, 0) || TYPE_OVERFLOW(off_t, 0))
962 SCREWUP("Unexpected off_t/time_t size");
963
949 setimes = targisdir = 0; 964 setimes = targisdir = 0;
950 mask = umask(0); 965 mask = umask(0);
951 if (!pflag) 966 if (!pflag)
@@ -1004,8 +1019,7 @@ sink(int argc, char **argv)
1004 ull = strtoull(cp, &cp, 10); 1019 ull = strtoull(cp, &cp, 10);
1005 if (!cp || *cp++ != ' ') 1020 if (!cp || *cp++ != ' ')
1006 SCREWUP("mtime.sec not delimited"); 1021 SCREWUP("mtime.sec not delimited");
1007 if ((time_t)ull < 0 || 1022 if (TYPE_OVERFLOW(time_t, ull))
1008 (unsigned long long)(time_t)ull != ull)
1009 setimes = 0; /* out of range */ 1023 setimes = 0; /* out of range */
1010 mtime.tv_sec = ull; 1024 mtime.tv_sec = ull;
1011 mtime.tv_usec = strtol(cp, &cp, 10); 1025 mtime.tv_usec = strtol(cp, &cp, 10);
@@ -1017,8 +1031,7 @@ sink(int argc, char **argv)
1017 ull = strtoull(cp, &cp, 10); 1031 ull = strtoull(cp, &cp, 10);
1018 if (!cp || *cp++ != ' ') 1032 if (!cp || *cp++ != ' ')
1019 SCREWUP("atime.sec not delimited"); 1033 SCREWUP("atime.sec not delimited");
1020 if ((time_t)ull < 0 || 1034 if (TYPE_OVERFLOW(time_t, ull))
1021 (unsigned long long)(time_t)ull != ull)
1022 setimes = 0; /* out of range */ 1035 setimes = 0; /* out of range */
1023 atime.tv_sec = ull; 1036 atime.tv_sec = ull;
1024 atime.tv_usec = strtol(cp, &cp, 10); 1037 atime.tv_usec = strtol(cp, &cp, 10);
@@ -1051,10 +1064,15 @@ sink(int argc, char **argv)
1051 if (*cp++ != ' ') 1064 if (*cp++ != ' ')
1052 SCREWUP("mode not delimited"); 1065 SCREWUP("mode not delimited");
1053 1066
1054 for (size = 0; isdigit((unsigned char)*cp);) 1067 if (!isdigit((unsigned char)*cp))
1055 size = size * 10 + (*cp++ - '0'); 1068 SCREWUP("size not present");
1056 if (*cp++ != ' ') 1069 ull = strtoull(cp, &cp, 10);
1070 if (!cp || *cp++ != ' ')
1057 SCREWUP("size not delimited"); 1071 SCREWUP("size not delimited");
1072 if (TYPE_OVERFLOW(off_t, ull))
1073 SCREWUP("size out of range");
1074 size = (off_t)ull;
1075
1058 if ((strchr(cp, '/') != NULL) || (strcmp(cp, "..") == 0)) { 1076 if ((strchr(cp, '/') != NULL) || (strcmp(cp, "..") == 0)) {
1059 run_err("error: unexpected filename: %s", cp); 1077 run_err("error: unexpected filename: %s", cp);
1060 exit(1); 1078 exit(1);
@@ -1264,7 +1282,7 @@ void
1264usage(void) 1282usage(void)
1265{ 1283{
1266 (void) fprintf(stderr, 1284 (void) fprintf(stderr,
1267 "usage: scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n" 1285 "usage: scp [-346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
1268 " [-l limit] [-o ssh_option] [-P port] [-S program]\n" 1286 " [-l limit] [-o ssh_option] [-P port] [-S program]\n"
1269 " [[user@]host1:]file1 ... [[user@]host2:]file2\n"); 1287 " [[user@]host1:]file1 ... [[user@]host2:]file2\n");
1270 exit(1); 1288 exit(1);
@@ -1358,11 +1376,7 @@ allocbuf(BUF *bp, int fd, int blksize)
1358#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ 1376#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
1359 if (bp->cnt >= size) 1377 if (bp->cnt >= size)
1360 return (bp); 1378 return (bp);
1361 if (bp->buf == NULL) 1379 bp->buf = xrecallocarray(bp->buf, bp->cnt, size, 1);
1362 bp->buf = xmalloc(size);
1363 else
1364 bp->buf = xreallocarray(bp->buf, 1, size);
1365 memset(bp->buf, 0, size);
1366 bp->cnt = size; 1380 bp->cnt = size;
1367 return (bp); 1381 return (bp);
1368} 1382}