From e84122fd19d0e890c577b3f06e7e3e0e7b950266 Mon Sep 17 00:00:00 2001 From: minus Date: Sun, 22 Aug 2021 12:09:06 +0200 Subject: Fix hanging arp_check arp_check relied on select(2) decreasing the timeout. This doesn't seem to be the case on Linux anymore, thus arp_check tends to hang when the interface sees a lot of traffic. Calculating the timeout explicitly solves the problem. --- src/firejail/arp.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/firejail/arp.c b/src/firejail/arp.c index bbab9a6d9..c259fc0ad 100644 --- a/src/firejail/arp.c +++ b/src/firejail/arp.c @@ -20,6 +20,7 @@ #include "firejail.h" #include #include +#include #include //TCP/IP Protocol Suite for Linux #include #include @@ -188,9 +189,14 @@ int arp_check(const char *dev, uint32_t destaddr) { FD_SET(sock, &fds); int maxfd = sock; struct timeval ts; - ts.tv_sec = 0; // 0.5 seconds wait time - ts.tv_usec = 500000; + gettimeofday(&ts, NULL); + double timerend = ts.tv_sec + ts.tv_usec / 1000000.0 + 0.5; while (1) { + gettimeofday(&ts, NULL); + double now = ts.tv_sec + ts.tv_usec / 1000000.0; + double timeout = timerend - now; + ts.tv_sec = timeout; + ts.tv_usec = (timeout - ts.tv_sec) * 1000000; int nready = select(maxfd + 1, &fds, (fd_set *) 0, (fd_set *) 0, &ts); if (nready < 0) errExit("select"); @@ -201,8 +207,8 @@ int arp_check(const char *dev, uint32_t destaddr) { } if (sendto (sock, frame, 14 + sizeof(ArpHdr), 0, (struct sockaddr *) &addr, sizeof (addr)) <= 0) errExit("send"); - ts.tv_sec = 0; // 0.5 seconds wait time - ts.tv_usec = 500000; + gettimeofday(&ts, NULL); + timerend = ts.tv_sec + ts.tv_usec / 1000000.0 + 0.5; fflush(0); } else { -- cgit v1.2.3-70-g09d2