aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-03-11 11:34:44 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-03-11 11:39:05 +0100
commit3d306bffc5981b083ebb365c51e93c2231ff9b22 (patch)
treec47a63aca8a473ae610ffb5aa2d8b8e9584e06fc
parent39dfb4de38fc5b31ca4472dbf45bcde3bb0d6e77 (diff)
downloadbusybox-w32-3d306bffc5981b083ebb365c51e93c2231ff9b22.tar.gz
busybox-w32-3d306bffc5981b083ebb365c51e93c2231ff9b22.tar.bz2
busybox-w32-3d306bffc5981b083ebb365c51e93c2231ff9b22.zip
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 <vda.linux@googlemail.com>
-rw-r--r--networking/udhcp/dhcpd.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c
index db3ab4f00..19f94a2d7 100644
--- a/networking/udhcp/dhcpd.c
+++ b/networking/udhcp/dhcpd.c
@@ -853,6 +853,9 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
853 /* Would rather not do read_config before daemonization - 853 /* Would rather not do read_config before daemonization -
854 * otherwise NOMMU machines will parse config twice */ 854 * otherwise NOMMU machines will parse config twice */
855 read_config(argv[0] ? argv[0] : DHCPD_CONF_FILE); 855 read_config(argv[0] ? argv[0] : DHCPD_CONF_FILE);
856 /* prevent poll timeout overflow */
857 if (server_config.auto_time > INT_MAX / 1000)
858 server_config.auto_time = INT_MAX / 1000;
856 859
857 /* Make sure fd 0,1,2 are open */ 860 /* Make sure fd 0,1,2 are open */
858 bb_sanitize_stdio(); 861 bb_sanitize_stdio();
@@ -914,14 +917,26 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
914 } 917 }
915 918
916 udhcp_sp_fd_set(pfds, server_socket); 919 udhcp_sp_fd_set(pfds, server_socket);
917 tv = timeout_end - monotonic_sec(); 920
918 /* Block here waiting for either signal or packet */ 921 new_tv:
919 retval = safe_poll(pfds, 2, server_config.auto_time ? tv * 1000 : -1); 922 tv = -1;
920 if (retval <= 0) { 923 if (server_config.auto_time) {
921 if (retval == 0) { 924 tv = timeout_end - monotonic_sec();
925 if (tv <= 0) {
926 write_leases:
922 write_leases(); 927 write_leases();
923 goto continue_with_autotime; 928 goto continue_with_autotime;
924 } 929 }
930 tv *= 1000;
931 }
932
933 /* Block here waiting for either signal or packet */
934 retval = poll(pfds, 2, tv);
935 if (retval <= 0) {
936 if (retval == 0)
937 goto write_leases;
938 if (errno == EINTR)
939 goto new_tv;
925 /* < 0 and not EINTR: should not happen */ 940 /* < 0 and not EINTR: should not happen */
926 bb_perror_msg_and_die("poll"); 941 bb_perror_msg_and_die("poll");
927 } 942 }