From: Samuel J. Greear Date: Thu, 9 Sep 2010 01:19:09 +0000 (+0000) Subject: userland - dhclient - Fix possible infinite loop from unhandled poll(2) return X-Git-Url: https://gitweb.dragonflybsd.org/~lentferj/dragonfly.git/commitdiff_plain/a05d48e6c7b12ad7abca8e3a3264413ac6f54003 userland - dhclient - Fix possible infinite loop from unhandled poll(2) return * This -probably- doesn't happen, but exercise some defensive programming here. This will prevent dhclient from running away and eating 100% cpu in the event of an error on the socket. Plus, we let the user know something went wrong. --- diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index 1d7882971e..9d421ed15b 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -57,6 +57,7 @@ #include #include #include +#include #include "dhcpd.h" #include "privsep.h" @@ -64,6 +65,8 @@ #define CLIENT_PATH "PATH=/usr/bin:/usr/sbin:/bin:/sbin" #define DEFAULT_LEASE_TIME 43200 /* 12 hours... */ #define TIME_MAX 2147483647 +#define POLL_FAILURES 10 +#define POLL_FAILURE_WAIT 1 /* Back off multiplier (seconds) */ time_t cur_time; @@ -2123,7 +2126,7 @@ int fork_privchld(int fd, int fd2) { struct pollfd pfd[1]; - int nfds; + int nfds, pfail = 0; switch (fork()) { case -1: @@ -2153,8 +2156,16 @@ fork_privchld(int fd, int fd2) if (errno != EINTR) error("poll error"); - if (nfds == 0 || !(pfd[0].revents & POLLIN)) + /* + * Handle temporary errors, but bail if they persist. + */ + if (nfds == 0 || !(pfd[0].revents & POLLIN)) { + if (pfail > POLL_FAILURES) + error("poll failed > %d times", POLL_FAILURES); + sleep(pfail * POLL_FAILURE_WAIT); + pfail++; continue; + } dispatch_imsg(fd); }