busybox/networking
Denys Vlasenko 3293bc1469 udhcpd: fix "not dying on SIGTERM"
Fixes:
	commit 52a515d187
	"udhcp: use poll() instead of select()"
	Feb 16 2017

udhcp_sp_read() is meant to check whether signal pipe indeed has some data to read.
In the above commit, it was changed as follows:

-	if (!FD_ISSET(signal_pipe.rd, rfds))
+	if (!pfds[0].revents)
		return 0;

The problem is, the check was working for select() purely by accident.
Caught signal interrupts select()/poll() syscalls, they return with EINTR
(regardless of SA_RESTART flag in sigaction). _Then_ signal handler is invoked.
IOW: they can't see any changes to fd state caused by signal haldler
(in our case, signal handler makes signal pipe ready to be read).

For select(), it means that rfds[] bit array is unmodified, bit of signal
pipe's read fd is still set, and the above check "works": it thinks select()
says there is data to read.

This accident does not work for poll(): .revents stays clear, and we do not
try reading signal pipe as we should. In udhcpd, we fall through and block
in socket read. Further SIGTERM signals simply cause socket read to be
interrupted and then restarted (since SIGTERM handler has SA_RESTART=1).

Fixing this as follows: remove the check altogether. Set signal pipe read fd
to nonblocking mode. Always read it in udhcp_sp_read().
If read fails, assume it's EAGAIN and return 0 ("no signal seen").

udhcpd avoids reading signal pipe on every recvd packet by looping if EINTR
(using safe_poll()) - thus ensuring we have correct .revents for all fds -
and calling udhcp_sp_read() only if pfds[0].revents!=0.

udhcpc performs much fewer reads (typically it sleeps >99.999% of the time),
there is no need to optimize it: can call udhcp_sp_read() after each poll
unconditionally.

To robustify socket reads, unconditionally set pfds[1].revents=0
in udhcp_sp_fd_set() (which is before poll), and check it before reading
network socket in udhcpd.

TODO:
This might still fail: if pfds[1].revents=POLLIN, socket read may still block.
There are rare cases when select/poll indicates that data can be read,
but then actual read still blocks (one such case is UDP packets with
wrong checksum). General advise is, if you use a poll/select loop,
keep all your fds nonblocking.
Maybe we should also do that to our network sockets?

function                                             old     new   delta
udhcp_sp_setup                                        55      65     +10
udhcp_sp_fd_set                                       54      60      +6
udhcp_sp_read                                         46      36     -10
udhcpd_main                                         1451    1437     -14
udhcpc_main                                         2723    2708     -15
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/3 up/down: 16/-39)            Total: -23 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2018-03-10 19:34:39 +01:00
..
libiproute ip: fix "ip -oneline a" 2018-03-08 15:55:07 +01:00
ssl_helper
ssl_helper-wolfssl Update information on building httpd and wget helpers 2016-12-22 15:13:37 +01:00
udhcp udhcpd: fix "not dying on SIGTERM" 2018-03-10 19:34:39 +01:00
arp.c config: deindent all help texts 2017-07-21 09:50:55 +02:00
arping.c arping: code shrink 2018-02-11 21:16:24 +01:00
brctl.c brctl: make it NOEXEC 2017-08-06 20:14:02 +02:00
Config.src config: deindent all help texts 2017-07-21 09:50:55 +02:00
dnsd.c config: deindent all help texts 2017-07-21 09:50:55 +02:00
ether-wake.c getopt32: remove opt_complementary 2017-08-08 21:55:02 +02:00
ftpd.c ftpd: handle restarts past 2147483647 bytes. closes 10741 2018-02-05 19:06:40 +01:00
ftpgetput.c wget: add EPSV support 2018-02-06 15:48:12 +01:00
hostname.c regularize format of source file headers, no code changes 2017-09-18 16:28:43 +02:00
httpd_helpers.sh Update information on building httpd and wget helpers 2016-12-22 15:13:37 +01:00
httpd_indexcgi.c
httpd_post_upload.cgi Make POST upload example script easier to use 2016-12-22 15:33:11 +01:00
httpd_ssi.c
httpd.c use gmtime_r() instead of gmtime() 2018-03-06 18:11:47 +01:00
ifconfig.c networking/interface.c: get rid of global "smallint interface_opt_a" 2018-03-05 17:46:17 +01:00
ifenslave.c getopt32: remove applet_long_options 2017-08-08 17:09:40 +02:00
ifplugd.c zcip: fix slow environment leak 2017-07-22 03:04:20 +02:00
ifupdown.c whitespace and comment format fixes, no code changes 2017-10-05 14:40:24 +02:00
inetd.c inetd,mount: add comment with example of flags to build with libtirpc 2018-02-13 18:20:28 +01:00
interface.c networking/interface.c: get rid of global data 2018-03-05 18:30:33 +01:00
ip.c remove stray newline in "iplink --help" 2018-03-08 16:06:18 +01:00
ipcalc.c getopt32: remove opt_complementary 2017-08-08 21:55:02 +02:00
isrv_identd.c config: deindent all help texts 2017-07-21 09:50:55 +02:00
isrv.c Spelling fixes in comments, documentation, tests and examples 2017-04-17 16:13:32 +02:00
isrv.h
Kbuild.src Convert all networking/* applets to "new style" applet definitions 2016-11-23 09:05:14 +01:00
nameif.c regularize format of source file headers, no code changes 2017-09-18 16:28:43 +02:00
nbd-client.c regularize format of source file headers, no code changes 2017-09-18 16:28:43 +02:00
nc_bloaty.c getopt32: remove opt_complementary 2017-08-08 21:55:02 +02:00
nc.c whitespace and comment format fixes, no code changes 2017-10-05 15:19:25 +02:00
netstat.c config: deindent all help texts 2017-07-21 09:50:55 +02:00
nslookup.c config: deindent all help texts 2017-07-21 09:50:55 +02:00
ntpd.c ntpd: do run the script at leat once in 11 minutes 2017-12-26 20:19:37 +01:00
ntpd.diff
parse_pasv_epsv.c fix a thinko in parse_pasv_epsv.c 2018-02-06 17:11:15 +01:00
ping.c ping: don't call monotonic_us twice per sending the ping 2018-02-13 23:53:24 +01:00
pscan.c getopt32: remove opt_complementary 2017-08-08 21:55:02 +02:00
route.c whitespace and comment format fixes, no code changes 2017-10-05 15:19:25 +02:00
slattach.c getopt32: remove opt_complementary 2017-08-08 21:55:02 +02:00
ssl_client.c wget: initial support for ftps:// 2018-02-06 15:15:08 +01:00
tc.c ip: fix crash in "ip neigh show" 2018-02-08 08:42:37 +01:00
tcpudp_perhost.c tcpudp: shrink per-host rate-limiting code 2018-02-27 13:03:44 +01:00
tcpudp_perhost.h tcpudp: shrink per-host rate-limiting code 2018-02-27 13:03:44 +01:00
tcpudp.c tcpudp: shrink per-host rate-limiting code 2018-02-27 13:03:44 +01:00
telnet.c whitespace and comment format fixes, no code changes 2017-10-05 15:19:25 +02:00
telnetd.c getopt32: remove opt_complementary 2017-08-08 21:55:02 +02:00
telnetd.ctrlSQ.patch
telnetd.IAC_test.sh telnetd: fix corner case of input processing of 0xff bytes 2016-10-12 19:13:46 +02:00
tftp.c randomconfig fixes 2017-12-31 17:30:02 +01:00
tls_aes.c Move get_unaligned_le32() macros to platform.h 2017-07-15 20:22:25 +02:00
tls_aes.h tls: fold AES CBC en/decryption into single functions 2017-02-04 16:23:49 +01:00
tls_pstm_montgomery_reduce.c tls: remove last int16 local variables in pstm code 2017-07-15 17:19:38 +02:00
tls_pstm_mul_comba.c tls: remove last int16 local variables in pstm code 2017-07-15 17:19:38 +02:00
tls_pstm_sqr_comba.c tls: remove last int16 local variables in pstm code 2017-07-15 17:19:38 +02:00
tls_pstm.c tls: remove last int16 local variables in pstm code 2017-07-15 17:19:38 +02:00
tls_pstm.h tls: avoid using int16 in pstm code 2017-04-03 21:53:29 +02:00
tls_rsa.c tls: commented out psPool_t use 2017-01-19 15:51:00 +01:00
tls_rsa.h tls: commented out psPool_t use 2017-01-19 15:51:00 +01:00
tls_symmetric.h tls: set TLS_DEBUG to 0; placate a gcc indentation warning 2017-01-23 01:15:13 +01:00
tls.c tls: remove redundant floor prevention 2018-02-14 17:37:41 +01:00
tls.h tls: fix pstm asm constraint problem 2017-07-15 17:13:08 +02:00
traceroute.c Fix build failures if MAXHOSTNAMELEN or MAXPATHLEN is not defined 2017-10-31 15:59:19 +01:00
tunctl.c getopt32: remove opt_complementary 2017-08-08 21:55:02 +02:00
vconfig.c regularize format of source file headers, no code changes 2017-09-18 16:28:43 +02:00
wget.c wget: fix fetching of https URLs with http proxy 2018-03-05 00:19:33 +01:00
whois.c regularize format of source file headers, no code changes 2017-09-18 16:28:43 +02:00
zcip.c whitespace and comment format fixes, no code changes 2017-10-05 15:19:25 +02:00