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 b4db851980ba..a533eb097412 100644
--- a/scp.c
+++ b/scp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scp.c,v 1.187 2016/09/12 01:22:38 deraadt Exp $ */
+/* $OpenBSD: scp.c,v 1.192 2017/05/31 09:15:42 deraadt 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,9 @@
#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -403,7 +406,11 @@ main(int argc, char **argv)
switch (ch) {
/* User-visible flags. */
case '1':
+ fatal("SSH protocol v.1 is no longer supported");
+ break;
case '2':
+ /* Ignored */
+ break;
case '4':
case '6':
case 'C':
@@ -915,6 +922,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 +950,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 +1011,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 +1023,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);
@@ -1043,10 +1056,15 @@ sink(int argc, char **argv)
if (*cp++ != ' ')
SCREWUP("mode not delimited");
- for (size = 0; isdigit((unsigned char)*cp);)
- size = size * 10 + (*cp++ - '0');
- if (*cp++ != ' ')
+ if (!isdigit((unsigned char)*cp))
+ SCREWUP("size not present");
+ ull = strtoull(cp, &cp, 10);
+ if (!cp || *cp++ != ' ')
SCREWUP("size not delimited");
+ if (TYPE_OVERFLOW(off_t, ull))
+ SCREWUP("size out of range");
+ size = (off_t)ull;
+
if ((strchr(cp, '/') != NULL) || (strcmp(cp, "..") == 0)) {
run_err("error: unexpected filename: %s", cp);
exit(1);
@@ -1256,7 +1274,7 @@ void
usage(void)
{
(void) fprintf(stderr,
- "usage: scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
+ "usage: scp [-346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
" [-l limit] [-o ssh_option] [-P port] [-S program]\n"
" [[user@]host1:]file1 ... [[user@]host2:]file2\n");
exit(1);
@@ -1350,11 +1368,7 @@ allocbuf(BUF *bp, int fd, int blksize)
#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */
if (bp->cnt >= size)
return (bp);
- if (bp->buf == NULL)
- bp->buf = xmalloc(size);
- else
- bp->buf = xreallocarray(bp->buf, 1, size);
- memset(bp->buf, 0, size);
+ bp->buf = xrecallocarray(bp->buf, bp->cnt, size, 1);
bp->cnt = size;
return (bp);
}