[DynInst_API:] [dyninst/dyninst] 2fc593: proccontrol: don't terminate/delete a freed proces...


Date: Wed, 08 Jul 2026 18:43:58 -0700
From: bbiiggppiigg <noreply@xxxxxxxxxx>
Subject: [DynInst_API:] [dyninst/dyninst] 2fc593: proccontrol: don't terminate/delete a freed proces...
  Branch: refs/heads/bbiiggppiigg/fix-processset-terminate-uaf
  Home:   https://github.com/dyninst/dyninst
  Commit: 2fc5931b5d00ee94bc9dad583be7872edb36766a
      https://github.com/dyninst/dyninst/commit/2fc5931b5d00ee94bc9dad583be7872edb36766a
  Author: Hsuan-Heng Wu <bbiiggppiigg@xxxxxxxxx>
  Date:   2026-07-08 (Wed, 08 Jul 2026)

  Changed paths:
    M proccontrol/src/procset.C

  Log Message:
  -----------
  proccontrol: don't terminate/delete a freed process in ProcessSet::terminate

ProcessSet::terminate snapshots the group's processes as raw int_process*
pointers, then calls waitAndHandleEvents(false) to drain preTerminate side
effects before looping over the snapshot to terminate() and finally delete
each process.

If one of the snapshotted processes finishes exiting during that
intervening event handling, its int_process is deleted: ~int_process nulls
the owning Process wrapper's llproc_, but the raw int_process* captured in
the snapshot is left dangling.  The later terminate() then makes a virtual
call (plat_terminate) on freed memory -- observed as "pure virtual method
called" / SIGABRT once the freed block still carries the base-class vtable
-- and the final loop double-deletes it.

The window is narrow, so this is normally latent; it becomes a reliable,
roaming crash under anything that shifts teardown event timing (e.g. a
full testsuite -all run, where whichever managed process exits inside the
window is the victim, while each test passes in isolation).

Snapshot the reference-counted Process::ptr wrappers instead of raw
int_process*.  The wrapper always outlives the int_process, so llproc()
is always safe to call and returns NULL exactly when the int_process has
been freed.  Re-derive llproc() after each waitAndHandleEvents and skip
any process that was freed, in both the terminate loop and the final
delete loop, so a process reclaimed mid-teardown is never terminated or
double-deleted.

Co-Authored-By: Claude Opus 4.8 <noreply@xxxxxxxxxxxxx>



To unsubscribe from these emails, change your notification settings at https://github.com/dyninst/dyninst/settings/notifications
[← Prev in Thread] Current Thread [Next in Thread→]
  • [DynInst_API:] [dyninst/dyninst] 2fc593: proccontrol: don't terminate/delete a freed proces..., bbiiggppiigg <=