From 7f4e69f88567b43deee0199355bbead575b6a3c5 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Wed, 25 Jan 2023 15:11:14 -0500 Subject: [PATCH] Fix: use-after-free in dog_eat() 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 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dogmove.c b/src/dogmove.c index ce4ab4a73..cdb19c9a8 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -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;