From 0968d062480cb8159b9790d25b58653d4559a122 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Tue, 12 May 2020 00:27:13 +0100 Subject: [PATCH] Make prayer timeouts longer in very long games This is a security fix, intended to avoid a DoS attack (that has been used in practice against public servers) in which a situation is created in which the same short loop of commands can be run over and over indefinitely; this causes a lot of CPU usage on the public server as it simulates the game turns, and requires hardly any network or CPU usage for an attacker. Once the turn counter goes above 100000, the average prayer timeout increases by 1 for every additional 100 turns spent. Thus, even with a ring of slow digestion, nutrition prayers will no longer be possible after turn 2 million or so. This is unlikely to have any noticeable effect on any strategy that does not rely heavily on prayer for nutrition; even in an implausible 200000-turn game, prayer timeout will only be increased by 1000 or so, which should be easily manageable for a character that powerful. --- src/pray.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pray.c b/src/pray.c index 7718bc247..e0f104601 100644 --- a/src/pray.c +++ b/src/pray.c @@ -1217,6 +1217,14 @@ aligntyp g_align; if (kick_on_butt) u.ublesscnt += kick_on_butt * rnz(1000); + /* Avoid games that go into infinite loops of copy-pasted commands with no + human interaction; this is a DoS vector against the computer running + NetHack. Once the turn counter is over 100000, every additional 100 turns + increases the prayer timeout by 1, thus eventually nutrition prayers will + fail and some other source of nutrition will be required. */ + if (g.moves > 100000L) + u.ublesscnt += (g.moves - 100000L) / 100; + return; }