summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2017-04-27 11:53:13 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2017-04-27 11:53:13 +0000
commitb2ac06e2fcbb2bcf89ec0af764355e48b422ab4c (patch)
tree8776c4d4317b98978c14f8797f9b58c1a88c6d60 /usr.bin
parentba08f4b365e763549ae679f06ddd066d4c666400 (diff)
Avoid potential signed int overflow when parsing the file size.
Use strtoul() instead of parsing manually. OK djm@
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/ssh/scp.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/usr.bin/ssh/scp.c b/usr.bin/ssh/scp.c
index 1674714b1d6..dcf68372544 100644
--- a/usr.bin/ssh/scp.c
+++ b/usr.bin/ssh/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.188 2017/04/27 11:53: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).
@@ -1022,10 +1022,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 ((off_t)ull < 0 || (unsigned long long)(off_t)ull != 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);