]> granicus.if.org Git - nethack/commitdiff
fix #H7659 - accessing freed memory by cutworm()
authorPatR <rankin@nethack.org>
Tue, 4 Dec 2018 02:57:01 +0000 (18:57 -0800)
committerPatR <rankin@nethack.org>
Tue, 4 Dec 2018 02:57:01 +0000 (18:57 -0800)
hmon() can destroy the weapon being used, and known_hitum() would
still pass the pointer to the freed object to cutworm().  Remember the
relevant weapon attribute before using and maybe freeing the object,
then pass that attribute instead of the whole weapon.  Also pass
'more-likely-to-cut' for axes in addition to blades.

thimonst() behaved similarly, although due to much different code
paths none of the objects that might get to hmon() were then passed to
cutworm(), so it wasn't vulnerable.  But pass 'more-likely-to-cut'
for axes instead of for blades when thrown.

doc/fixes36.2
include/extern.h
src/dothrow.c
src/uhitm.c
src/worm.c

index 53ba866ea30d779bf33917862398379a3ae8f69c..07d1fe75617217174dd39466dc47cac0078c31ef 100644 (file)
@@ -236,6 +236,8 @@ to emphasize that it's not a light source, change description of wielded Sting
        from "(glowing)" to nothing (not warm enough to feel) when blind
 glowing Sting quivers if hero becomes blind and quivering Sting glows if
        blindness ends; it worked for timed blindness but not for blindfold
+weapon (wielded pie, egg, potion, boomerang) might be destroyed when hitting a
+       long worm, then freed memory was accessed to decide whether to cut it
 
 
 Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
index 16b10859bed1b9dd7d8ad3e48317c26a4eb4cb7c..4f1c8d6fa584c8da1f9a8c2ddd3b60ff4be87a72 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 extern.h        $NHDT-Date: 1543745352 2018/12/02 10:09:12 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.664 $ */
+/* NetHack 3.6 extern.h        $NHDT-Date: 1543892214 2018/12/04 02:56:54 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.665 $ */
 /* Copyright (c) Steve Creps, 1988.                              */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -2834,7 +2834,7 @@ E void FDECL(worm_move, (struct monst *));
 E void FDECL(worm_nomove, (struct monst *));
 E void FDECL(wormgone, (struct monst *));
 E void FDECL(wormhitu, (struct monst *));
-E void FDECL(cutworm, (struct monst *, XCHAR_P, XCHAR_P, struct obj *));
+E void FDECL(cutworm, (struct monst *, XCHAR_P, XCHAR_P, BOOLEAN_P));
 E void FDECL(see_wsegs, (struct monst *));
 E void FDECL(detect_wsegs, (struct monst *, BOOLEAN_P));
 E void FDECL(save_worm, (int, int));
index d40857447b636e179e3021cf1bc7308b58afdc72..e55c9b7d676bf73801da03298786b2394272c885 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 dothrow.c       $NHDT-Date: 1525012611 2018/04/29 14:36:51 $  $NHDT-Branch: master $:$NHDT-Revision: 1.137 $ */
+/* NetHack 3.6 dothrow.c       $NHDT-Date: 1543892215 2018/12/04 02:56:55 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.152 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2013. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -1652,13 +1652,16 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */
         }
 
         if (tmp >= dieroll) {
-            boolean wasthrown = (thrownobj != 0);
+            boolean wasthrown = (thrownobj != 0),
+                    /* remember weapon attribute; hmon() might destroy obj */
+                    chopper = is_axe(obj);
 
             /* attack hits mon */
             if (hmode == HMON_APPLIED)
                 u.uconduct.weaphit++;
             if (hmon(mon, obj, hmode, dieroll)) { /* mon still alive */
-                cutworm(mon, bhitpos.x, bhitpos.y, obj);
+                if (mon->wormno)
+                    cutworm(mon, bhitpos.x, bhitpos.y, chopper);
             }
             exercise(A_DEX, TRUE);
             /* if hero was swallowed and projectile killed the engulfer,
@@ -1668,8 +1671,9 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */
             if (wasthrown && !thrownobj)
                 return 1;
 
-            /* projectiles other than magic stones
-               sometimes disappear when thrown */
+            /* projectiles other than magic stones sometimes disappear
+               when thrown; projectiles aren't among the types of weapon
+               that hmon() might have destroyed so obj is intact */
             if (objects[otyp].oc_skill < P_NONE
                 && objects[otyp].oc_skill > -P_BOOMERANG
                 && !objects[otyp].oc_magic) {
index a14218543adbb42c04ce1413b8479f600303c73f..0412bb599b71374fc6cf58a6ff507342bacd5622 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 uhitm.c $NHDT-Date: 1542765366 2018/11/21 01:56:06 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.185 $ */
+/* NetHack 3.6 uhitm.c $NHDT-Date: 1543892215 2018/12/04 02:56:55 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.195 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2012. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -449,7 +449,9 @@ int rollneeded, armorpenalty; /* for monks */
 struct attack *uattk;
 int dieroll;
 {
-    register boolean malive = TRUE;
+    boolean malive = TRUE,
+            /* hmon() might destroy weapon; remember aspect for cutworm */
+            slice_or_chop = (weapon && (is_blade(weapon) || is_axe(weapon)));
 
     if (override_confirmation) {
         /* this may need to be generalized if weapons other than
@@ -490,7 +492,7 @@ int dieroll;
                 u.uconduct.weaphit = oldweaphit;
             }
             if (mon->wormno && *mhit)
-                cutworm(mon, x, y, weapon);
+                cutworm(mon, x, y, slice_or_chop);
         }
     }
     return malive;
index 4e9d144b1fcb55ba7be32a65b543d5b3c6f4ae6d..faf257710cf1f1c51b0aa59d87178bdbdf5acdc9 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 worm.c  $NHDT-Date: 1456528599 2016/02/26 23:16:39 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.20 $ */
+/* NetHack 3.6 worm.c  $NHDT-Date: 1543892216 2018/12/04 02:56:56 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.28 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2009. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -314,10 +314,10 @@ register struct monst *worm;
  *  that both halves will survive.
  */
 void
-cutworm(worm, x, y, weap)
+cutworm(worm, x, y, cuttier)
 struct monst *worm;
 xchar x, y;
-struct obj *weap;
+boolean cuttier; /* hit is by wielded blade or axe or by thrown axe */
 {
     register struct wseg *curr, *new_tail;
     register struct monst *new_worm;
@@ -330,12 +330,10 @@ struct obj *weap;
     if (x == worm->mx && y == worm->my)
         return; /* hit on head */
 
-    /* cutting goes best with a bladed weapon */
-    cut_chance = rnd(20); /* Normally  1-16 does not cut */
-    /* Normally 17-20 does */
-
-    if (weap && is_blade(weap)) /* With a blade 1- 6 does not cut */
-        cut_chance += 10;       /*              7-20 does         */
+    /* cutting goes best with a cuttier weapon */
+    cut_chance = rnd(20); /* Normally     1-16 does not cut, 17-20 does, */
+    if (cuttier)
+        cut_chance += 10; /* with a blade 1- 6 does not cut,  7-20 does. */
 
     if (cut_chance < 17)
         return; /* not good enough */