Fix heap-use-after-free when attacking monster with potion

Attacking a monster which has a passive attack (e.g. a red mold) with a
wielded potion that breaks during the attack, the variable weapon would
not be correctly reset and passive() would be called with the pointer to the
freed object.
This commit is contained in:
Patric Mueller
2021-07-17 12:44:50 +02:00
parent 35a6939b5e
commit 4c1f2ffa48
2 changed files with 9 additions and 6 deletions

View File

@@ -568,6 +568,7 @@ deal with gold leaving a shop via scatter()
defer encumbrance check during polymorph to new man; newman() -> redist_attr()
-> encumber_msg() could report change in encumbrance that immediately
became obsolete if polyman() subsequently restored old attributes
fix heap-use-after-free when attacking monster with potion
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository

View File

@@ -4441,6 +4441,7 @@ hmonas(struct monst *mon)
int i, tmp, armorpenalty, sum[NATTK], nsum = MM_MISS,
dhit = 0, attknum = 0;
int dieroll, multi_claw = 0;
boolean monster_survived;
/* not used here but umpteen mhitm_ad_xxxx() need this */
g.vis = (canseemon(mon) || distu(mon->mx, mon->my) <= 2);
@@ -4521,17 +4522,18 @@ hmonas(struct monst *mon)
dieroll = rnd(20);
dhit = (tmp > dieroll || u.uswallow);
/* caller must set g.bhitpos */
if (!known_hitum(mon, weapon, &dhit, tmp,
armorpenalty, mattk, dieroll)) {
monster_survived = known_hitum(mon, weapon, &dhit, tmp,
armorpenalty, mattk, dieroll);
/* originalweapon points to an equipment slot which might
now be empty if the weapon was destroyed during the hit;
passive(,weapon,...) won't call passive_obj() in that case */
weapon = *originalweapon; /* might receive passive erosion */
if (!monster_survived) {
/* enemy dead, before any special abilities used */
sum[i] = MM_DEF_DIED;
break;
} else
sum[i] = dhit ? MM_HIT : MM_MISS;
/* originalweapon points to an equipment slot which might
now be empty if the weapon was destroyed during the hit;
passive(,weapon,...) won't call passive_obj() in that case */
weapon = *originalweapon; /* might receive passive erosion */
/* might be a worm that gets cut in half; if so, early return */
if (m_at(u.ux + u.dx, u.uy + u.dy) != mon) {
i = NATTK; /* skip additional attacks */