From: Denys Vlasenko Date: Sun, 11 Mar 2018 10:34:44 +0000 (+0100) Subject: udhcpd: clamp down huge auto_times to ~2M seconds, better EINTR poll handling X-Git-Tag: 1_28_2~2 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=62b7083c13a9afc16b872367db93f8a775164343;p=oweals%2Fbusybox.git udhcpd: clamp down huge auto_times to ~2M seconds, better EINTR poll handling EINTR _should_ only happen on two signals we trap, and safe_poll _should_ work here just fine, but there were kernel bugs where spurious EINTRs happen (e.g. on ptrace attach). Be safe. function old new delta udhcpd_main 1437 1468 +31 Signed-off-by: Denys Vlasenko --- diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index f1368cc4d..cfa994791 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -853,6 +853,9 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) /* Would rather not do read_config before daemonization - * otherwise NOMMU machines will parse config twice */ read_config(argv[0] ? argv[0] : DHCPD_CONF_FILE); + /* prevent poll timeout overflow */ + if (server_config.auto_time > INT_MAX / 1000) + server_config.auto_time = INT_MAX / 1000; /* Make sure fd 0,1,2 are open */ bb_sanitize_stdio(); @@ -914,14 +917,26 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) } udhcp_sp_fd_set(pfds, server_socket); - tv = timeout_end - monotonic_sec(); - /* Block here waiting for either signal or packet */ - retval = safe_poll(pfds, 2, server_config.auto_time ? tv * 1000 : -1); - if (retval <= 0) { - if (retval == 0) { + + new_tv: + tv = -1; + if (server_config.auto_time) { + tv = timeout_end - monotonic_sec(); + if (tv <= 0) { + write_leases: write_leases(); goto continue_with_autotime; } + tv *= 1000; + } + + /* Block here waiting for either signal or packet */ + retval = poll(pfds, 2, tv); + if (retval <= 0) { + if (retval == 0) + goto write_leases; + if (errno == EINTR) + goto new_tv; /* < 0 and not EINTR: should not happen */ bb_perror_msg_and_die("poll"); }