]> granicus.if.org Git - nethack/commitdiff
Fix: use-after-free in dog_eat()
authorMichael Meyer <me@entrez.cc>
Wed, 25 Jan 2023 20:11:14 +0000 (15:11 -0500)
committerPasi Kallinen <paxed@alt.org>
Thu, 26 Jan 2023 06:30:00 +0000 (08:30 +0200)
I think moving the m_consume_obj call (which will free the eaten item)
further down should fix this without causing any really wacky message
sequencing issues, but if maintaining the exact order is important
obj->unpaid and its price could be cached before the free instead.

src/dogmove.c

index ce4ab4a737ad61314e6fa469d67322d0725b3607..cdb19c9a8989da4f47c0853ced8b4a22aa9b163f 100644 (file)
@@ -313,7 +313,6 @@ dog_eat(struct monst *mtmp,
         if (dogfood(mtmp, obj) == DOGFOOD && obj->invlet)
             edog->apport += (int) (200L / ((long) edog->dropdist + gm.moves
                                            - edog->droptime));
-        m_consume_obj(mtmp, obj);
         if (obj->unpaid) {
             /* edible item owned by shop has been thrown or kicked
                by hero and caught by tame or food-tameable monst */
@@ -322,6 +321,7 @@ dog_eat(struct monst *mtmp,
                   currency(oprice));
             /* m_consume_obj->delobj->obfree will handle actual shop billing update */
         }
+        m_consume_obj(mtmp, obj);
     }
 
     return (DEADMONSTER(mtmp)) ? 2 : 1;