Skip to content

Commit 1e736ab

Browse files
committed
Fix: potential use-after-free when monster threw lit oil
Specifically at melee range, and when the monster was carrying more oil that could ignite and explode. The code previously assumed that if there was more than 1 oil in the stack to throw that it would definitely still be around after the explosion to read the memory contents of, which was not true. Another ASan catch.
1 parent fb8830f commit 1e736ab

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

src/muse.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,7 +1716,7 @@ use_offensive(struct monst* mtmp)
17161716
* are not objects. Also set dknown in mthrowu.c.
17171717
*/
17181718
boolean isoil = (otmp->otyp == POT_OIL);
1719-
int origquan = otmp->quan;
1719+
struct obj *minvptr;
17201720
if (cansee(mtmp->mx, mtmp->my)) {
17211721
otmp->dknown = 1;
17221722
pline("%s hurls %s!", Monnam(mtmp), singular(otmp, doname));
@@ -1730,9 +1730,18 @@ use_offensive(struct monst* mtmp)
17301730
m_throw(mtmp, mtmp->mx, mtmp->my, sgn(mtmp->mux - mtmp->mx),
17311731
sgn(mtmp->muy - mtmp->my),
17321732
distmin(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy), otmp);
1733-
if (isoil && origquan > 1 && otmp->lamplit) {
1734-
/* origquan > 1: otmp is still valid */
1735-
end_burn(otmp, TRUE);
1733+
if (isoil) {
1734+
/* Possible situation: monster lights and throws 1 of a stack of oil
1735+
* point blank -> it explodes -> monster is caught in explosion ->
1736+
* monster's remaining oil ignites and explodes -> otmp is no longer
1737+
* valid. So we need to check whether otmp is still in monster's
1738+
* inventory or not. */
1739+
for (minvptr = mtmp->minvent; minvptr; minvptr = minvptr->nobj) {
1740+
if (minvptr == otmp)
1741+
break;
1742+
}
1743+
if (minvptr == otmp && otmp->lamplit)
1744+
end_burn(otmp, TRUE);
17361745
}
17371746
return 2;
17381747
}

0 commit comments

Comments
 (0)