diff options
author | dtucker@openbsd.org@openbsd.org <dtucker@openbsd.org@openbsd.org> | 2017-11-25 06:46:22 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2017-11-28 12:01:49 +1100 |
commit | 5db6fbf1438b108e5df3e79a1b4de544373bc2d4 (patch) | |
tree | 95f5df8248cca30df3ab00e70e80d28410be760c | |
parent | 2d638e986085bdf1a40310ed6e2307463db96ea0 (diff) |
upstream commit
Add monotime_ts and monotime_tv that return monotonic
timespec and timeval respectively. Replace calls to gettimeofday() in packet
timing with monotime_tv so that the callers will work over a clock step.
Should prevent integer overflow during clock steps reported by wangle6 at
huawei.com. "I like" markus@
OpenBSD-Commit-ID: 74d684264814ff806f197948b87aa732cb1b0b8a
-rw-r--r-- | misc.c | 87 | ||||
-rw-r--r-- | misc.h | 4 | ||||
-rw-r--r-- | packet.c | 6 | ||||
-rw-r--r-- | ssh-keyscan.c | 8 | ||||
-rw-r--r-- | sshconnect.c | 4 |
5 files changed, 60 insertions, 49 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.c,v 1.118 2017/10/25 00:17:08 djm Exp $ */ | 1 | /* $OpenBSD: misc.c,v 1.119 2017/11/25 06:46:22 dtucker Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2005,2006 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2005,2006 Damien Miller. All rights reserved. |
@@ -1259,8 +1259,8 @@ ms_subtract_diff(struct timeval *start, int *ms) | |||
1259 | { | 1259 | { |
1260 | struct timeval diff, finish; | 1260 | struct timeval diff, finish; |
1261 | 1261 | ||
1262 | gettimeofday(&finish, NULL); | 1262 | monotime_tv(&finish); |
1263 | timersub(&finish, start, &diff); | 1263 | timersub(&finish, start, &diff); |
1264 | *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000); | 1264 | *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000); |
1265 | } | 1265 | } |
1266 | 1266 | ||
@@ -1273,54 +1273,63 @@ ms_to_timeval(struct timeval *tv, int ms) | |||
1273 | tv->tv_usec = (ms % 1000) * 1000; | 1273 | tv->tv_usec = (ms % 1000) * 1000; |
1274 | } | 1274 | } |
1275 | 1275 | ||
1276 | time_t | 1276 | void |
1277 | monotime(void) | 1277 | monotime_ts(struct timespec *ts) |
1278 | { | 1278 | { |
1279 | #if defined(HAVE_CLOCK_GETTIME) && \ | 1279 | struct timeval tv; |
1280 | (defined(CLOCK_MONOTONIC) || defined(CLOCK_BOOTTIME)) | 1280 | #if defined(HAVE_CLOCK_GETTIME) && (defined(CLOCK_BOOTTIME) || \ |
1281 | struct timespec ts; | 1281 | defined(CLOCK_MONOTONIC) || defined(CLOCK_REALTIME)) |
1282 | static int gettime_failed = 0; | 1282 | static int gettime_failed = 0; |
1283 | 1283 | ||
1284 | if (!gettime_failed) { | 1284 | if (!gettime_failed) { |
1285 | #if defined(CLOCK_BOOTTIME) | 1285 | # ifdef CLOCK_BOOTTIME |
1286 | if (clock_gettime(CLOCK_BOOTTIME, &ts) == 0) | 1286 | if (clock_gettime(CLOCK_BOOTTIME, ts) == 0) |
1287 | return (ts.tv_sec); | 1287 | return; |
1288 | #endif | 1288 | # endif /* CLOCK_BOOTTIME */ |
1289 | #if defined(CLOCK_MONOTONIC) | 1289 | # ifdef CLOCK_MONOTONIC |
1290 | if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) | 1290 | if (clock_gettime(CLOCK_MONOTONIC, ts) == 0) |
1291 | return (ts.tv_sec); | 1291 | return; |
1292 | #endif | 1292 | # endif /* CLOCK_MONOTONIC */ |
1293 | # ifdef CLOCK_REALTIME | ||
1294 | /* Not monotonic, but we're almost out of options here. */ | ||
1295 | if (clock_gettime(CLOCK_REALTIME, ts) == 0) | ||
1296 | return; | ||
1297 | # endif /* CLOCK_REALTIME */ | ||
1293 | debug3("clock_gettime: %s", strerror(errno)); | 1298 | debug3("clock_gettime: %s", strerror(errno)); |
1294 | gettime_failed = 1; | 1299 | gettime_failed = 1; |
1295 | } | 1300 | } |
1296 | #endif /* HAVE_CLOCK_GETTIME && (CLOCK_MONOTONIC || CLOCK_BOOTTIME */ | 1301 | #endif /* HAVE_CLOCK_GETTIME && (BOOTTIME || MONOTONIC || REALTIME) */ |
1302 | gettimeofday(&tv, NULL); | ||
1303 | ts->tv_sec = tv.tv_sec; | ||
1304 | ts->tv_nsec = (long)tv.tv_usec * 1000; | ||
1305 | } | ||
1297 | 1306 | ||
1298 | return time(NULL); | 1307 | void |
1308 | monotime_tv(struct timeval *tv) | ||
1309 | { | ||
1310 | struct timespec ts; | ||
1311 | |||
1312 | monotime_ts(&ts); | ||
1313 | tv->tv_sec = ts.tv_sec; | ||
1314 | tv->tv_usec = ts.tv_nsec / 1000; | ||
1315 | } | ||
1316 | |||
1317 | time_t | ||
1318 | monotime(void) | ||
1319 | { | ||
1320 | struct timespec ts; | ||
1321 | |||
1322 | monotime_ts(&ts); | ||
1323 | return ts.tv_sec; | ||
1299 | } | 1324 | } |
1300 | 1325 | ||
1301 | double | 1326 | double |
1302 | monotime_double(void) | 1327 | monotime_double(void) |
1303 | { | 1328 | { |
1304 | #if defined(HAVE_CLOCK_GETTIME) && \ | ||
1305 | (defined(CLOCK_MONOTONIC) || defined(CLOCK_BOOTTIME)) | ||
1306 | struct timespec ts; | 1329 | struct timespec ts; |
1307 | static int gettime_failed = 0; | ||
1308 | |||
1309 | if (!gettime_failed) { | ||
1310 | #if defined(CLOCK_BOOTTIME) | ||
1311 | if (clock_gettime(CLOCK_BOOTTIME, &ts) == 0) | ||
1312 | return (ts.tv_sec + (double)ts.tv_nsec / 1000000000); | ||
1313 | #endif | ||
1314 | #if defined(CLOCK_MONOTONIC) | ||
1315 | if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) | ||
1316 | return (ts.tv_sec + (double)ts.tv_nsec / 1000000000); | ||
1317 | #endif | ||
1318 | debug3("clock_gettime: %s", strerror(errno)); | ||
1319 | gettime_failed = 1; | ||
1320 | } | ||
1321 | #endif /* HAVE_CLOCK_GETTIME && (CLOCK_MONOTONIC || CLOCK_BOOTTIME */ | ||
1322 | 1330 | ||
1323 | return (double)time(NULL); | 1331 | monotime_ts(&ts); |
1332 | return ts.tv_sec + ((double)ts.tv_nsec / 1000000000); | ||
1324 | } | 1333 | } |
1325 | 1334 | ||
1326 | void | 1335 | void |
@@ -1342,7 +1351,7 @@ bandwidth_limit(struct bwlimit *bw, size_t read_len) | |||
1342 | struct timespec ts, rm; | 1351 | struct timespec ts, rm; |
1343 | 1352 | ||
1344 | if (!timerisset(&bw->bwstart)) { | 1353 | if (!timerisset(&bw->bwstart)) { |
1345 | gettimeofday(&bw->bwstart, NULL); | 1354 | monotime_tv(&bw->bwstart); |
1346 | return; | 1355 | return; |
1347 | } | 1356 | } |
1348 | 1357 | ||
@@ -1350,7 +1359,7 @@ bandwidth_limit(struct bwlimit *bw, size_t read_len) | |||
1350 | if (bw->lamt < bw->thresh) | 1359 | if (bw->lamt < bw->thresh) |
1351 | return; | 1360 | return; |
1352 | 1361 | ||
1353 | gettimeofday(&bw->bwend, NULL); | 1362 | monotime_tv(&bw->bwend); |
1354 | timersub(&bw->bwend, &bw->bwstart, &bw->bwend); | 1363 | timersub(&bw->bwend, &bw->bwstart, &bw->bwend); |
1355 | if (!timerisset(&bw->bwend)) | 1364 | if (!timerisset(&bw->bwend)) |
1356 | return; | 1365 | return; |
@@ -1384,7 +1393,7 @@ bandwidth_limit(struct bwlimit *bw, size_t read_len) | |||
1384 | } | 1393 | } |
1385 | 1394 | ||
1386 | bw->lamt = 0; | 1395 | bw->lamt = 0; |
1387 | gettimeofday(&bw->bwstart, NULL); | 1396 | monotime_tv(&bw->bwstart); |
1388 | } | 1397 | } |
1389 | 1398 | ||
1390 | /* Make a template filename for mk[sd]temp() */ | 1399 | /* Make a template filename for mk[sd]temp() */ |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.h,v 1.67 2017/10/25 00:17:08 djm Exp $ */ | 1 | /* $OpenBSD: misc.h,v 1.68 2017/11/25 06:46:22 dtucker Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -67,6 +67,8 @@ char *tohex(const void *, size_t); | |||
67 | void sanitise_stdfd(void); | 67 | void sanitise_stdfd(void); |
68 | void ms_subtract_diff(struct timeval *, int *); | 68 | void ms_subtract_diff(struct timeval *, int *); |
69 | void ms_to_timeval(struct timeval *, int); | 69 | void ms_to_timeval(struct timeval *, int); |
70 | void monotime_ts(struct timespec *); | ||
71 | void monotime_tv(struct timeval *); | ||
70 | time_t monotime(void); | 72 | time_t monotime(void); |
71 | double monotime_double(void); | 73 | double monotime_double(void); |
72 | void lowercase(char *s); | 74 | void lowercase(char *s); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.c,v 1.266 2017/10/25 00:17:08 djm Exp $ */ | 1 | /* $OpenBSD: packet.c,v 1.267 2017/11/25 06:46:22 dtucker Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -1332,7 +1332,7 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1332 | for (;;) { | 1332 | for (;;) { |
1333 | if (state->packet_timeout_ms != -1) { | 1333 | if (state->packet_timeout_ms != -1) { |
1334 | ms_to_timeval(&timeout, ms_remain); | 1334 | ms_to_timeval(&timeout, ms_remain); |
1335 | gettimeofday(&start, NULL); | 1335 | monotime_tv(&start); |
1336 | } | 1336 | } |
1337 | if ((r = select(state->connection_in + 1, setp, | 1337 | if ((r = select(state->connection_in + 1, setp, |
1338 | NULL, NULL, timeoutp)) >= 0) | 1338 | NULL, NULL, timeoutp)) >= 0) |
@@ -1959,7 +1959,7 @@ ssh_packet_write_wait(struct ssh *ssh) | |||
1959 | for (;;) { | 1959 | for (;;) { |
1960 | if (state->packet_timeout_ms != -1) { | 1960 | if (state->packet_timeout_ms != -1) { |
1961 | ms_to_timeval(&timeout, ms_remain); | 1961 | ms_to_timeval(&timeout, ms_remain); |
1962 | gettimeofday(&start, NULL); | 1962 | monotime_tv(&start); |
1963 | } | 1963 | } |
1964 | if ((ret = select(state->connection_out + 1, | 1964 | if ((ret = select(state->connection_out + 1, |
1965 | NULL, setp, NULL, timeoutp)) >= 0) | 1965 | NULL, setp, NULL, timeoutp)) >= 0) |
diff --git a/ssh-keyscan.c b/ssh-keyscan.c index 258123ae8..a816a220e 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh-keyscan.c,v 1.115 2017/06/30 04:17:23 dtucker Exp $ */ | 1 | /* $OpenBSD: ssh-keyscan.c,v 1.116 2017/11/25 06:46:22 dtucker Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. | 3 | * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. |
4 | * | 4 | * |
@@ -377,7 +377,7 @@ conalloc(char *iname, char *oname, int keytype) | |||
377 | fdcon[s].c_len = 4; | 377 | fdcon[s].c_len = 4; |
378 | fdcon[s].c_off = 0; | 378 | fdcon[s].c_off = 0; |
379 | fdcon[s].c_keytype = keytype; | 379 | fdcon[s].c_keytype = keytype; |
380 | gettimeofday(&fdcon[s].c_tv, NULL); | 380 | monotime_tv(&fdcon[s].c_tv); |
381 | fdcon[s].c_tv.tv_sec += timeout; | 381 | fdcon[s].c_tv.tv_sec += timeout; |
382 | TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link); | 382 | TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link); |
383 | FD_SET(s, read_wait); | 383 | FD_SET(s, read_wait); |
@@ -411,7 +411,7 @@ static void | |||
411 | contouch(int s) | 411 | contouch(int s) |
412 | { | 412 | { |
413 | TAILQ_REMOVE(&tq, &fdcon[s], c_link); | 413 | TAILQ_REMOVE(&tq, &fdcon[s], c_link); |
414 | gettimeofday(&fdcon[s].c_tv, NULL); | 414 | monotime_tv(&fdcon[s].c_tv); |
415 | fdcon[s].c_tv.tv_sec += timeout; | 415 | fdcon[s].c_tv.tv_sec += timeout; |
416 | TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link); | 416 | TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link); |
417 | } | 417 | } |
@@ -545,7 +545,7 @@ conloop(void) | |||
545 | con *c; | 545 | con *c; |
546 | int i; | 546 | int i; |
547 | 547 | ||
548 | gettimeofday(&now, NULL); | 548 | monotime_tv(&now); |
549 | c = TAILQ_FIRST(&tq); | 549 | c = TAILQ_FIRST(&tq); |
550 | 550 | ||
551 | if (c && (c->c_tv.tv_sec > now.tv_sec || | 551 | if (c && (c->c_tv.tv_sec > now.tv_sec || |
diff --git a/sshconnect.c b/sshconnect.c index dc7a704d2..e29b069c9 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshconnect.c,v 1.287 2017/09/14 04:32:21 djm Exp $ */ | 1 | /* $OpenBSD: sshconnect.c,v 1.288 2017/11/25 06:46:22 dtucker Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -344,7 +344,7 @@ waitrfd(int fd, int *timeoutp) | |||
344 | struct timeval t_start; | 344 | struct timeval t_start; |
345 | int oerrno, r; | 345 | int oerrno, r; |
346 | 346 | ||
347 | gettimeofday(&t_start, NULL); | 347 | monotime_tv(&t_start); |
348 | pfd.fd = fd; | 348 | pfd.fd = fd; |
349 | pfd.events = POLLIN; | 349 | pfd.events = POLLIN; |
350 | for (; *timeoutp >= 0;) { | 350 | for (; *timeoutp >= 0;) { |