summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorguenther <guenther@openbsd.org>2013-06-17 04:48:42 +0000
committerguenther <guenther@openbsd.org>2013-06-17 04:48:42 +0000
commita012bd17dfdf73e61ae6ecb7f5e6f91c34659920 (patch)
treedc8ab16aa7caf56c04942179f50d341701e019f1
parentIn icmp_do_exthdr(), calculate the ICMP extension header checksums with (diff)
downloadwireguard-openbsd-a012bd17dfdf73e61ae6ecb7f5e6f91c34659920.tar.xz
wireguard-openbsd-a012bd17dfdf73e61ae6ecb7f5e6f91c34659920.zip
Handle time_t values as long long's when formatting them and when
parsing them from remote servers. Improve error checking in parsing of 'T' lines. ok dtucker@ deraadt@
-rw-r--r--bin/rcp/rcp.c52
-rw-r--r--usr.bin/ssh/scp.c63
2 files changed, 71 insertions, 44 deletions
diff --git a/bin/rcp/rcp.c b/bin/rcp/rcp.c
index 131f8bb6a47..aabe6992aa5 100644
--- a/bin/rcp/rcp.c
+++ b/bin/rcp/rcp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rcp.c,v 1.51 2013/06/01 20:59:25 dtucker Exp $ */
+/* $OpenBSD: rcp.c,v 1.52 2013/06/17 04:48:42 guenther Exp $ */
/* $NetBSD: rcp.c,v 1.9 1995/03/21 08:19:06 cgd Exp $ */
/*
@@ -381,6 +381,19 @@ tolocal(int argc, char *argv[])
free(user);
}
+int
+do_times(int fd, const struct stat *sb)
+{
+ /* strlen(2^64) == 20; strlen(10^6) == 7 */
+ char buf[(20 + 7 + 2) * 2 + 2];
+
+ (void)snprintf(buf, sizeof(buf), "T%llu 0 %llu 0\n",
+ (unsigned long long) (sb->st_mtime < 0 ? 0 : sb->st_mtime),
+ (unsigned long long) (sb->st_atime < 0 ? 0 : sb->st_atime));
+ (void)write(fd, buf, strlen(buf));
+ return (response());
+}
+
void
source(int argc, char *argv[])
{
@@ -427,15 +440,7 @@ syserr:
else
++last;
if (pflag) {
- /*
- * Make it compatible with possible future
- * versions expecting microseconds.
- */
- (void)snprintf(buf, sizeof(buf), "T%lu 0 %lu 0\n",
- (u_long) (stb.st_mtime < 0 ? 0 : stb.st_mtime),
- (u_long) (stb.st_atime < 0 ? 0 : stb.st_atime));
- (void)write(rem, buf, strlen(buf));
- if (response() < 0)
+ if (do_times(rem, &stb) < 0)
goto next;
}
#define MODEMASK (S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO)
@@ -500,11 +505,7 @@ rsource(char *name, struct stat *statp)
else
last++;
if (pflag) {
- (void)snprintf(path, sizeof(path), "T%ld 0 %ld 0\n",
- (long)statp->st_mtimespec.tv_sec,
- (long)statp->st_atimespec.tv_sec);
- (void)write(rem, path, strlen(path));
- if (response() < 0) {
+ if (do_times(rem, statp) < 0) {
closedir(dirp);
return;
}
@@ -543,6 +544,7 @@ sink(int argc, char *argv[])
enum { YES, NO, DISPLAYED } wrerr;
BUF *bp;
off_t i, j, size;
+ unsigned long long ull;
int amt, count, exists, first, mask, mode, ofd, omode;
int setimes, targisdir, wrerrno = 0;
char ch, *cp, *np, *targ, *why, *vect[1], buf[BUFSIZ];
@@ -599,17 +601,29 @@ sink(int argc, char *argv[])
if (*cp == 'T') {
setimes++;
cp++;
- mtime.tv_sec = strtol(cp, &cp, 10);
+ if (!isdigit((unsigned char)*cp))
+ SCREWUP("mtime.sec not present");
+ ull = strtoull(cp, &cp, 10);
if (!cp || *cp++ != ' ')
SCREWUP("mtime.sec not delimited");
+ if ((time_t)ull < 0 || (time_t)ull != ull)
+ setimes = 0; /* out of range */
+ mtime.tv_sec = ull;
mtime.tv_usec = strtol(cp, &cp, 10);
- if (!cp || *cp++ != ' ')
+ if (!cp || *cp++ != ' ' || mtime.tv_usec < 0 ||
+ mtime.tv_usec > 999999)
SCREWUP("mtime.usec not delimited");
- atime.tv_sec = strtol(cp, &cp, 10);
+ if (!isdigit((unsigned char)*cp))
+ SCREWUP("atime.sec not present");
+ ull = strtoull(cp, &cp, 10);
if (!cp || *cp++ != ' ')
SCREWUP("atime.sec not delimited");
+ if ((time_t)ull < 0 || (time_t)ull != ull)
+ setimes = 0; /* out of range */
+ atime.tv_sec = ull;
atime.tv_usec = strtol(cp, &cp, 10);
- if (!cp || *cp++ != '\0')
+ if (!cp || *cp++ != '\0' || atime.tv_usec < 0 ||
+ atime.tv_usec > 999999)
SCREWUP("atime.usec not delimited");
(void)write(rem, "", 1);
continue;
diff --git a/usr.bin/ssh/scp.c b/usr.bin/ssh/scp.c
index eddf65778b5..f36286b3fe7 100644
--- a/usr.bin/ssh/scp.c
+++ b/usr.bin/ssh/scp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scp.c,v 1.175 2013/06/04 19:12:23 dtucker Exp $ */
+/* $OpenBSD: scp.c,v 1.176 2013/06/17 04:48:42 guenther Exp $ */
/*
* scp - secure remote copy. This is basically patched BSD rcp which
* uses ssh to do the data transfer (instead of using rcmd).
@@ -529,6 +529,24 @@ scpio(void *_cnt, size_t s)
return 0;
}
+static int
+do_times(int fd, int verb, const struct stat *sb)
+{
+ /* strlen(2^64) == 20; strlen(10^6) == 7 */
+ char buf[(20 + 7 + 2) * 2 + 2];
+
+ (void)snprintf(buf, sizeof(buf), "T%llu 0 %llu 0\n",
+ (unsigned long long) (sb->st_mtime < 0 ? 0 : sb->st_mtime),
+ (unsigned long long) (sb->st_atime < 0 ? 0 : sb->st_atime));
+ if (verb) {
+ fprintf(stderr, "File mtime %lld atime %lld\n",
+ (long long)sb->st_mtime, (long long)sb->st_atime);
+ fprintf(stderr, "Sending file timestamps: %s", buf);
+ }
+ (void) atomicio(vwrite, fd, buf, strlen(buf));
+ return (response());
+}
+
void
toremote(char *targ, int argc, char **argv)
{
@@ -753,21 +771,7 @@ syserr: run_err("%s: %s", name, strerror(errno));
++last;
curfile = last;
if (pflag) {
- /*
- * Make it compatible with possible future
- * versions expecting microseconds.
- */
- (void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n",
- (u_long) (stb.st_mtime < 0 ? 0 : stb.st_mtime),
- (u_long) (stb.st_atime < 0 ? 0 : stb.st_atime));
- if (verbose_mode) {
- fprintf(stderr, "File mtime %ld atime %ld\n",
- (long)stb.st_mtime, (long)stb.st_atime);
- fprintf(stderr, "Sending file timestamps: %s",
- buf);
- }
- (void) atomicio(vwrite, remout, buf, strlen(buf));
- if (response() < 0)
+ if (do_times(remout, verbose_mode, &stb) < 0)
goto next;
}
#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
@@ -841,11 +845,7 @@ rsource(char *name, struct stat *statp)
else
last++;
if (pflag) {
- (void) snprintf(path, sizeof(path), "T%lu 0 %lu 0\n",
- (u_long) statp->st_mtime,
- (u_long) statp->st_atime);
- (void) atomicio(vwrite, remout, path, strlen(path));
- if (response() < 0) {
+ if (do_times(remout, verbose_mode, statp) < 0) {
closedir(dirp);
return;
}
@@ -891,6 +891,7 @@ sink(int argc, char **argv)
int amt, exists, first, ofd;
mode_t mode, omode, mask;
off_t size, statbytes;
+ unsigned long long ull;
int setimes, targisdir, wrerrno = 0;
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
struct timeval tv[2];
@@ -949,17 +950,29 @@ sink(int argc, char **argv)
if (*cp == 'T') {
setimes++;
cp++;
- mtime.tv_sec = strtol(cp, &cp, 10);
+ if (!isdigit((unsigned char)*cp))
+ SCREWUP("mtime.sec not present");
+ ull = strtoull(cp, &cp, 10);
if (!cp || *cp++ != ' ')
SCREWUP("mtime.sec not delimited");
+ if ((time_t)ull < 0 || (time_t)ull != ull)
+ setimes = 0; /* out of range */
+ mtime.tv_sec = ull;
mtime.tv_usec = strtol(cp, &cp, 10);
- if (!cp || *cp++ != ' ')
+ if (!cp || *cp++ != ' ' || mtime.tv_usec < 0 ||
+ mtime.tv_usec > 999999)
SCREWUP("mtime.usec not delimited");
- atime.tv_sec = strtol(cp, &cp, 10);
+ if (!isdigit((unsigned char)*cp))
+ SCREWUP("atime.sec not present");
+ ull = strtoull(cp, &cp, 10);
if (!cp || *cp++ != ' ')
SCREWUP("atime.sec not delimited");
+ if ((time_t)ull < 0 || (time_t)ull != ull)
+ setimes = 0; /* out of range */
+ atime.tv_sec = ull;
atime.tv_usec = strtol(cp, &cp, 10);
- if (!cp || *cp++ != '\0')
+ if (!cp || *cp++ != '\0' || atime.tv_usec < 0 ||
+ atime.tv_usec > 999999)
SCREWUP("atime.usec not delimited");
(void) atomicio(vwrite, remout, "", 1);
continue;