diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-03-11 11:34:44 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-03-11 11:39:05 +0100 |
commit | 3d306bffc5981b083ebb365c51e93c2231ff9b22 (patch) | |
tree | c47a63aca8a473ae610ffb5aa2d8b8e9584e06fc /networking/udhcp | |
parent | 39dfb4de38fc5b31ca4472dbf45bcde3bb0d6e77 (diff) | |
download | busybox-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>
Diffstat (limited to 'networking/udhcp')
-rw-r--r-- | networking/udhcp/dhcpd.c | 25 |
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 | } |