Skip to content

Commit

Permalink
Fix: potential use-after-free when monster threw lit oil
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
copperwater committed Sep 26, 2021
1 parent fb8830f commit 1e736ab
Showing 1 changed file with 13 additions and 4 deletions.
17 changes: 13 additions & 4 deletions src/muse.c
Original file line number Diff line number Diff line change
Expand Up @@ -1716,7 +1716,7 @@ use_offensive(struct monst* mtmp)
* are not objects. Also set dknown in mthrowu.c.
*/
boolean isoil = (otmp->otyp == POT_OIL);
int origquan = otmp->quan;
struct obj *minvptr;
if (cansee(mtmp->mx, mtmp->my)) {
otmp->dknown = 1;
pline("%s hurls %s!", Monnam(mtmp), singular(otmp, doname));
Expand All @@ -1730,9 +1730,18 @@ use_offensive(struct monst* mtmp)
m_throw(mtmp, mtmp->mx, mtmp->my, sgn(mtmp->mux - mtmp->mx),
sgn(mtmp->muy - mtmp->my),
distmin(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy), otmp);
if (isoil && origquan > 1 && otmp->lamplit) {
/* origquan > 1: otmp is still valid */
end_burn(otmp, TRUE);
if (isoil) {
/* Possible situation: monster lights and throws 1 of a stack of oil
* point blank -> it explodes -> monster is caught in explosion ->
* monster's remaining oil ignites and explodes -> otmp is no longer
* valid. So we need to check whether otmp is still in monster's
* inventory or not. */
for (minvptr = mtmp->minvent; minvptr; minvptr = minvptr->nobj) {
if (minvptr == otmp)
break;
}
if (minvptr == otmp && otmp->lamplit)
end_burn(otmp, TRUE);
}
return 2;
}
Expand Down

0 comments on commit 1e736ab

Please sign in to comment.