summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHauke Mehrtens2026-04-08 22:47:39 +0000
committerHauke Mehrtens2026-06-18 22:06:47 +0000
commit9db2171daf28d7ad0b3bcaa7477f3f9ff8077ad8 (patch)
tree963ead704088403bd52ff7c579738a93f8a70dfe
parent48111664b51f1beb1a1c29b3c7c6c0956a84738f (diff)
downloadlibubox-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.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/usock.c b/usock.c
index cf82bd2..b2a2e99 100644
--- a/usock.c
+++ b/usock.c
@@ -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