From 1dd44b7eeaba691853975641d7220166d278b3f5 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sun, 11 Mar 2012 11:49:46 +0100 Subject: [PATCH] Fix player_login() to obey max_idle for output, too player_login() flushes the output queue before receiving input. The receive obeys max_idle, the flush doesn't. Which means a client could hog the thread indefinitely. 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. --- src/lib/player/login.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/lib/player/login.c b/src/lib/player/login.c index 31afa27af..ba415d8bf 100644 --- a/src/lib/player/login.c +++ b/src/lib/player/login.c @@ -76,6 +76,7 @@ static struct cmndstr login_coms[] = { void player_login(void *ud) { + time_t deadline; char buf[128]; char space[128]; int ac; @@ -87,13 +88,14 @@ player_login(void *ud) pr_id(player, C_INIT, "Empire server ready\n"); for (;;) { + deadline = player->curup + minutes(max_idle); if (io_outputwaiting(player->iop)) { - if (io_output(player->iop, (time_t)-1) <= 0) + if (io_output(player->iop, deadline) <= 0) break; continue; } if (io_gets(player->iop, buf, sizeof(buf)) < 0) { - res = io_input(player->iop, player->curup + minutes(max_idle)); + res = io_input(player->iop, deadline); if (res <= 0) { if (res == 0 && !io_eof(player->iop)) pr_id(player, C_DATA, "idle connection terminated\n"); -- 2.43.0