diff options
| author | Hauke Mehrtens | 2026-04-08 22:47:39 +0000 |
|---|---|---|
| committer | Hauke Mehrtens | 2026-06-18 22:06:47 +0000 |
| commit | 9db2171daf28d7ad0b3bcaa7477f3f9ff8077ad8 (patch) | |
| tree | 963ead704088403bd52ff7c579738a93f8a70dfe | |
| parent | 48111664b51f1beb1a1c29b3c7c6c0956a84738f (diff) | |
| download | libubox-9db2171daf28d7ad0b3bcaa7477f3f9ff8077ad8.tar.gz | |
usock: fix integer overflow in timeout calculations
usock_timeout_remaining() and poll_restart() compute millisecond
differences by multiplying a time_t difference by 1000 and storing the
result in int. For large timeouts (>~24 days), this overflows int and
produces incorrect values, turning a long timeout into an immediate
expiry.
Use int64_t for the intermediate calculation and clamp to INT_MAX
before returning.
Link: https://github.com/openwrt/libubox/pull/42
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
(cherry picked from commit d30b9cc1a02de4a0a06b917b2eb8b0723211382c)
| -rw-r--r-- | usock.c | 19 |
1 files changed, 13 insertions, 6 deletions
@@ -27,7 +27,9 @@ #include <errno.h> #include <string.h> #include <stdbool.h> +#include <stdint.h> #include <stdio.h> +#include <limits.h> #include "usock.h" #include "utils.h" @@ -113,6 +115,7 @@ usock_inet_notimeout(int type, struct addrinfo *result, void *addr) static int poll_restart(struct pollfd *fds, int nfds, int timeout) { struct timespec ts, cur; + int64_t remaining; int msec = timeout % 1000; int ret; @@ -131,10 +134,11 @@ static int poll_restart(struct pollfd *fds, int nfds, int timeout) return ret; clock_gettime(CLOCK_MONOTONIC, &cur); - timeout = (ts.tv_sec - cur.tv_sec) * 1000; - timeout += (ts.tv_nsec - cur.tv_nsec) / 1000000; - if (timeout <= 0) + remaining = ((int64_t)ts.tv_sec - (int64_t)cur.tv_sec) * 1000; + remaining += (ts.tv_nsec - cur.tv_nsec) / 1000000; + if (remaining <= 0) return 0; + timeout = remaining > INT_MAX ? INT_MAX : (int)remaining; } } @@ -152,13 +156,16 @@ static int usock_check_connect(int fd) static int usock_timeout_remaining(struct timespec *deadline) { struct timespec cur; - int msec; + int64_t msec; clock_gettime(CLOCK_MONOTONIC, &cur); - msec = (deadline->tv_sec - cur.tv_sec) * 1000; + msec = ((int64_t)deadline->tv_sec - (int64_t)cur.tv_sec) * 1000; msec += (deadline->tv_nsec - cur.tv_nsec) / 1000000; - return msec > 0 ? msec : 0; + if (msec > INT_MAX) + return INT_MAX; + + return msec > 0 ? (int)msec : 0; } #define USOCK_MAX_CANDIDATES 8 |