diff options
author | 2021-08-22 12:09:06 +0200 | |
---|---|---|
committer | 2021-08-22 12:09:06 +0200 | |
commit | e84122fd19d0e890c577b3f06e7e3e0e7b950266 (patch) | |
tree | ad7c81e61d1942e9f62613bf007e8ab80dc0f66b /src | |
parent | Give fbuilder full original environment (diff) | |
download | firejail-e84122fd19d0e890c577b3f06e7e3e0e7b950266.tar.gz firejail-e84122fd19d0e890c577b3f06e7e3e0e7b950266.tar.zst firejail-e84122fd19d0e890c577b3f06e7e3e0e7b950266.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/arp.c | 14 |
1 files 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 @@ | |||
20 | #include "firejail.h" | 20 | #include "firejail.h" |
21 | #include <sys/socket.h> | 21 | #include <sys/socket.h> |
22 | #include <sys/ioctl.h> | 22 | #include <sys/ioctl.h> |
23 | #include <sys/time.h> | ||
23 | #include <linux/if_ether.h> //TCP/IP Protocol Suite for Linux | 24 | #include <linux/if_ether.h> //TCP/IP Protocol Suite for Linux |
24 | #include <net/if.h> | 25 | #include <net/if.h> |
25 | #include <netinet/in.h> | 26 | #include <netinet/in.h> |
@@ -188,9 +189,14 @@ int arp_check(const char *dev, uint32_t destaddr) { | |||
188 | FD_SET(sock, &fds); | 189 | FD_SET(sock, &fds); |
189 | int maxfd = sock; | 190 | int maxfd = sock; |
190 | struct timeval ts; | 191 | struct timeval ts; |
191 | ts.tv_sec = 0; // 0.5 seconds wait time | 192 | gettimeofday(&ts, NULL); |
192 | ts.tv_usec = 500000; | 193 | double timerend = ts.tv_sec + ts.tv_usec / 1000000.0 + 0.5; |
193 | while (1) { | 194 | while (1) { |
195 | gettimeofday(&ts, NULL); | ||
196 | double now = ts.tv_sec + ts.tv_usec / 1000000.0; | ||
197 | double timeout = timerend - now; | ||
198 | ts.tv_sec = timeout; | ||
199 | ts.tv_usec = (timeout - ts.tv_sec) * 1000000; | ||
194 | int nready = select(maxfd + 1, &fds, (fd_set *) 0, (fd_set *) 0, &ts); | 200 | int nready = select(maxfd + 1, &fds, (fd_set *) 0, (fd_set *) 0, &ts); |
195 | if (nready < 0) | 201 | if (nready < 0) |
196 | errExit("select"); | 202 | errExit("select"); |
@@ -201,8 +207,8 @@ int arp_check(const char *dev, uint32_t destaddr) { | |||
201 | } | 207 | } |
202 | if (sendto (sock, frame, 14 + sizeof(ArpHdr), 0, (struct sockaddr *) &addr, sizeof (addr)) <= 0) | 208 | if (sendto (sock, frame, 14 + sizeof(ArpHdr), 0, (struct sockaddr *) &addr, sizeof (addr)) <= 0) |
203 | errExit("send"); | 209 | errExit("send"); |
204 | ts.tv_sec = 0; // 0.5 seconds wait time | 210 | gettimeofday(&ts, NULL); |
205 | ts.tv_usec = 500000; | 211 | timerend = ts.tv_sec + ts.tv_usec / 1000000.0 + 0.5; |
206 | fflush(0); | 212 | fflush(0); |
207 | } | 213 | } |
208 | else { | 214 | else { |