From f009b3d8c9d2273bf2e51ef9a23fbfedc2da09df Mon Sep 17 00:00:00 2001 From: "X.organic" Date: Sat, 3 Sep 2022 02:58:47 +0000 Subject: [PATCH] Fix use-after-frees around mobjs --- src/k_kart.c | 2 +- src/p_enemy.c | 6 +++--- src/p_mobj.c | 17 +++++++++-------- src/p_saveg.c | 4 ++-- src/p_tick.c | 1 + src/r_fps.c | 2 +- 6 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 0a0b0ea4..d040b8d2 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4286,7 +4286,7 @@ static void K_MoveHeldObjects(player_t *player) } - if (cur->tracer) + if (cur->tracer && !P_MobjWasRemoved(cur->tracer)) { fixed_t diffx, diffy, diffz; diff --git a/src/p_enemy.c b/src/p_enemy.c index bbb72848..761eebc7 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -2149,7 +2149,7 @@ void A_Boss1Laser(mobj_t *actor) if (z - floorz < mobjinfo[MT_EGGMOBILE_FIRE].height>>1) { point = P_SpawnMobj(x, y, floorz+1, MT_EGGMOBILE_FIRE); - point->target = actor; + P_SetTarget(&point->target, actor); point->destscale = 3*FRACUNIT; point->scalespeed = FRACUNIT>>2; point->fuse = TICRATE; @@ -2533,7 +2533,7 @@ void A_1upThinker(mobj_t *actor) actor->frame = 0; if (actor->tracer) { P_RemoveMobj(actor->tracer); - actor->tracer = NULL; + P_SetTarget(&actor->target, NULL); } return; } @@ -6547,7 +6547,7 @@ void A_Boss2PogoTarget(mobj_t *actor) if (actor->info->missilestate) // spawn the pogo stick collision box { mobj_t *pogo = P_SpawnMobj(actor->x, actor->y, actor->z - mobjinfo[actor->info->missilestate].height, (mobjtype_t)actor->info->missilestate); - pogo->target = actor; + P_SetTarget(&pogo->target, actor); } actor->reactiontime = 1; diff --git a/src/p_mobj.c b/src/p_mobj.c index 9abde82b..530dd37d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -4231,7 +4231,7 @@ static void P_Boss3Thinker(mobj_t *mobj) dummy = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->info->mass); dummy->angle = mobj->angle; dummy->threshold = way + 1; - dummy->tracer = mobj; + P_SetTarget(&dummy->tracer, mobj); do way2 = (way + P_RandomRange(1,3)) % 5; // dummy 2 has to be careful, @@ -4239,7 +4239,7 @@ static void P_Boss3Thinker(mobj_t *mobj) dummy = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->info->mass); dummy->angle = mobj->angle; dummy->threshold = way2 + 1; - dummy->tracer = mobj; + P_SetTarget(&dummy->tracer, mobj); CONS_Debug(DBG_GAMELOGIC, "Eggman path %d - Dummy selected paths %d and %d\n", mobj->threshold, way + 1, dummy->threshold); P_LinedefExecute(LE_PINCHPHASE, mobj, NULL); @@ -4550,8 +4550,8 @@ static void P_Boss4Thinker(mobj_t *mobj) P_SetTarget(&seg->target, mobj); for (i = 0; i < 9; i++) { - seg->hnext = P_SpawnMobj(mobj->x, mobj->y, z, MT_EGGMOBILE4_MACE); - seg->hnext->hprev = seg; + P_SetTarget(&seg->hnext, P_SpawnMobj(mobj->x, mobj->y, z, MT_EGGMOBILE4_MACE)); + P_SetTarget(&seg->hnext->hprev, seg); seg = seg->hnext; } } @@ -5111,10 +5111,10 @@ static void P_Boss9Thinker(mobj_t *mobj) if (mo2->type == MT_BOSS9GATHERPOINT) { if (last) - last->hnext = mo2; + P_SetTarget(&last->hnext, mo2); else - mobj->hnext = mo2; - mo2->hprev = last; + P_SetTarget(&mobj->hnext, mo2); + P_SetTarget(&mo2->hprev, last); last = mo2; } } @@ -9800,7 +9800,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj_t *side = P_SpawnMobj(mobj->x + FINECOSINE((ang>>ANGLETOFINESHIFT) & FINEMASK), mobj->y + FINESINE((ang>>ANGLETOFINESHIFT) & FINEMASK), mobj->z, MT_PINETREE_SIDE); side->angle = ang; - side->target = mobj; + P_SetTarget(&side->target, mobj); side->threshold = i; } break; @@ -10312,6 +10312,7 @@ void P_RemoveSavegameMobj(mobj_t *mobj) // free block P_RemoveThinker((thinker_t *)mobj); + R_RemoveMobjInterpolator(mobj); } static CV_PossibleValue_t respawnitemtime_cons_t[] = {{1, "MIN"}, {300, "MAX"}, {0, NULL}}; diff --git a/src/p_saveg.c b/src/p_saveg.c index c79d7c7e..f79b3f57 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3009,14 +3009,14 @@ static void P_RelinkPointers(void) { temp = (UINT32)(size_t)mobj->hnext; mobj->hnext = NULL; - if (!(mobj->hnext = P_FindNewPosition(temp))) + if (!P_SetTarget(&mobj->hnext, P_FindNewPosition(temp))) CONS_Debug(DBG_GAMELOGIC, "hnext not found on %d\n", mobj->type); } if (mobj->hprev) { temp = (UINT32)(size_t)mobj->hprev; mobj->hprev = NULL; - if (!(mobj->hprev = P_FindNewPosition(temp))) + if (!P_SetTarget(&mobj->hprev, P_FindNewPosition(temp))) CONS_Debug(DBG_GAMELOGIC, "hprev not found on %d\n", mobj->type); } if (mobj->player && mobj->player->capsule) diff --git a/src/p_tick.c b/src/p_tick.c index e79bf1b5..5386b1db 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -231,6 +231,7 @@ void P_RemoveThinkerDelayed(void *pthinker) * thinker->prev->next = thinker->next */ (next->prev = currentthinker = thinker->prev)->next = next; } + R_DestroyLevelInterpolators(thinker); Z_Free(thinker); } } diff --git a/src/r_fps.c b/src/r_fps.c index 3d3258eb..2ed03979 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -684,7 +684,7 @@ void R_RemoveMobjInterpolator(mobj_t *mobj) if (interpolated_mobjs_len == 0) return; - for (i = 0; i < interpolated_mobjs_len - 1; i++) + for (i = 0; i < interpolated_mobjs_len; i++) { if (interpolated_mobjs[i] == mobj) {