Fix pr_player() and upr_player() to obey max_idle
authorMarkus Armbruster <armbru@pond.sub.org>
Sun, 11 Mar 2012 14:07:48 +0000 (15:07 +0100)
committerMarkus Armbruster <armbru@pond.sub.org>
Thu, 26 Apr 2012 17:43:42 +0000 (19:43 +0200)
The output queue flush can block indefinitely.  Permits a client to
hog the thread 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.

src/lib/subs/pr.c

index 57064e8fdb466b3a1e178e238948931018734e93..fb46bef021873aa2717c2ba4bb0e1cd5d16554c3 100644 (file)
@@ -58,6 +58,7 @@
 #include "journal.h"
 #include "misc.h"
 #include "nat.h"
+#include "optlist.h"
 #include "player.h"
 #include "proto.h"
 #include "prototypes.h"
@@ -333,7 +334,9 @@ player_output_some(void)
 {
     time_t deadline;
 
-    deadline = (time_t)(player->may_sleep == PLAYER_SLEEP_FREELY ? -1 : 0);
+    deadline = player->curup + minutes(max_idle);
+    if (player->may_sleep != PLAYER_SLEEP_FREELY)
+       deadline = 0;
     while (io_output_if_queue_long(player->iop, deadline) > 0)
        ;
 }