[git commit branch/1_28_stable] udhcpd: clamp down huge auto_times to ~2M seconds, better EINTR poll handling

Denys Vlasenko vda.linux at googlemail.com
Sun Mar 11 22:04:05 UTC 2018


commit: https://git.busybox.net/busybox/commit/?id=62b7083c13a9afc16b872367db93f8a775164343
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/1_28_stable

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 at googlemail.com>
---
 networking/udhcp/dhcpd.c | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)

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");
 		}


More information about the busybox-cvs mailing list