From: Markus Armbruster Date: Sun, 11 Mar 2012 09:06:04 +0000 (+0100) Subject: Fix io_close() to obey deadline for output, too X-Git-Tag: v4.3.30~34 X-Git-Url: http://git.pond.sub.org/?p=empserver;a=commitdiff_plain;h=5ce099f6717479dad4c293583caf5568c9d729e6 Fix io_close() to obey deadline for output, too A client can delay thread exit indefinitely by not reading output. Broken in commit 08b94556 (v4.3.20) "Reimplement max_idle without a separate thread". Until then, the idle thread aborted a stuck attempt to flush output. Denial of service seems possible. Note that commit 904822e3 moved flushing the output queue from player_login() to io_close(). It also made io_close() wait for the client to close the connection. That wait obeys the deadline. --- diff --git a/src/lib/empthread/io.c b/src/lib/empthread/io.c index af6b97dcf..0a44916d7 100644 --- a/src/lib/empthread/io.c +++ b/src/lib/empthread/io.c @@ -105,6 +105,16 @@ io_open(int fd, int flags, int bufsize) return iop; } +/* + * Close IOP. + * Flush output and wait for the client to close the connection. + * Wait at most until DEADLINE. (time_t)-1 means wait as long as it + * takes (no timeout). + * Both the flush and the wait can be separately cut short by + * empth_wakeup(). This is almost certainly not what you want. If + * you need early wakeup, better fix this function not to go to sleep + * after wakeup during flush. + */ void io_close(struct iop *iop, time_t deadline) { @@ -112,7 +122,7 @@ io_close(struct iop *iop, time_t deadline) char buf[IO_BUFSIZE]; int ret; - while (io_output(iop, (time_t)-1) > 0) ; + while (io_output(iop, deadline) > 0) ; shutdown(iop->fd, SHUT_WR); while (empth_select(iop->fd, EMPTH_FD_READ, io_timeout(&timeout, deadline)) > 0) {