diff options
author | 2013-06-17 04:48:42 +0000 | |
---|---|---|
committer | 2013-06-17 04:48:42 +0000 | |
commit | a012bd17dfdf73e61ae6ecb7f5e6f91c34659920 (patch) | |
tree | dc8ab16aa7caf56c04942179f50d341701e019f1 | |
parent | In icmp_do_exthdr(), calculate the ICMP extension header checksums with (diff) | |
download | wireguard-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.c | 52 | ||||
-rw-r--r-- | usr.bin/ssh/scp.c | 63 |
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; |