]> granicus.if.org Git - nethack/commitdiff
Fix: potential use-after-free in expels()
authorMichael Meyer <me@entrez.cc>
Mon, 28 Nov 2022 22:16:21 +0000 (17:16 -0500)
committerPatR <rankin@nethack.org>
Wed, 30 Nov 2022 22:54:05 +0000 (14:54 -0800)
An engulfing monster can expel you onto a level teleporter or other
level-changing trap, in which case it may (under highly specific
circumstances[1]) no longer have been in memory by the time mtmp->mx/my
were accessed to see whether the "Brrooaa" message should be printed.
It also doesn't make much sense to print that message by the time you've
already fallen through a portal, trapdoor, etc, onto another level, so I
think moving it before the spoteffects() call kills two birds with one
stone.

[1] The highly specific circumstances: you must die due to illness or
some other timeout (or generally die on your own turn rather than the
monsters' turn, since this ensures the level change isn't deferred until
the end of the turn), while engulfed above a level teleporter [or maybe
another similar trap -- I tested with a level teleporter], and be
lifesaved, while positioned such that the engulfer can't follow you
through the levelport after expulsion (e.g. surrounded by other
monsters).  It may happen under some other conditions too, but even if
so it's pretty rare and was tough to reproduce.

src/mhitu.c

index 3856681216c75468b7c1cf40ea93eb47b52417de..9ed14381e1d90d69444275ddbafc9ec2294d7c6e 100644 (file)
@@ -270,10 +270,10 @@ expels(
     unstuck(mtmp); /* ball&chain returned in unstuck() */
     mnexto(mtmp, RLOC_NOMSG);
     newsym(u.ux, u.uy);
-    spoteffects(TRUE);
     /* to cover for a case where mtmp is not in a next square */
     if (um_dist(mtmp->mx, mtmp->my, 1))
         pline("Brrooaa...  You land hard at some distance.");
+    spoteffects(TRUE);
 }
 
 /* select a monster's next attack, possibly substituting for its usual one */