Skip to content

Never clear IDA residue out from under a live server - #231

Open
subwire wants to merge 1 commit into
recover-stale-ida-databasefrom
stale-clear-process-guard
Open

Never clear IDA residue out from under a live server#231
subwire wants to merge 1 commit into
recover-stale-ida-databasefrom
stale-clear-process-guard

Conversation

@subwire

@subwire subwire commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Targets recover-stale-ida-database (#226) directly — this is a safety fix for that PR, found while benchmarking it. Merge into #226 before #226 lands, or land them together.

The hole

#226 gates the clear on "no live server is registered for this project". That trusts the registry — and the registry is not a reliable witness. Caught in the act:

$ decompiler list --json
{ "registry_dir": "/home/ctf/.local/state/declib/servers", "servers": [] }

$ ps auxww | grep declib
ctf 1432 ... --server-id 25c68aada6 --project-dir .../re_project
ctf 1465 ... --server-id 4407c27e6c --project-dir /tmp/re_analyst_crackme04.Xxx3tb
ctf 1521 ... --server-id 58d279d42a --project-dir /tmp/re_32_compare_declib.sEQYhU
ctf 1600 ... --server-id 957351bdd1 --project-dir /tmp/re_analyst_crackme04.Xxx3tb

Four healthy servers, zero in the registry. Two of them share a project dir.

With the registry-based gate, the next load onto one of those dirs deletes the unpacked database of a server that is still using it — turning a registry glitch into actual corruption. This is not hypothetical: the load that printed cleared stale IDA database residue from a previous crash (5 file(s)) was deleting a live server's files, and it reproduces on demand.

Fix

Establish ownership from the process table, which cannot silently lose a live process, rather than from the registry.

Verified both directions:

live owner present (registry blind) no owner
before 5 files deleted from under it cleared ✅
after files survive; second load fails honestly, because IDA cannot open a database another process holds cleared ✅

So #226's actual purpose is intact — genuine crash residue is still removed.

If psutil is unavailable the check assumes the project is owned and skips: refusing to clear costs a reload, clearing wrongly costs the database.

Note

The empty-registry condition itself is a separate bug and is not fixed here — this only makes the clear safe in its presence. Worth tracking on its own; it is also why load appears to "hang" for the full --timeout while the server it is waiting for is up and healthy.

🤖 Generated with Claude Code

The clear was gated on "no live server is registered for this project".
That trusts the registry, and the registry is not a reliable witness: a
running server can be missing from it. Caught in the act on a benchmark
run --

    $ decompiler list --json
    { "servers": [] }
    $ ps auxww | grep declib
    ... --server-id 25c68aada6 --project-dir .../re_project
    ... --server-id 4407c27e6c --project-dir /tmp/re_analyst_crackme04.Xxx3tb
    ... --server-id 58d279d42a --project-dir /tmp/re_32_compare_declib.sEQYhU
    ... --server-id 957351bdd1 --project-dir /tmp/re_analyst_crackme04.Xxx3tb

Four healthy servers, zero in the registry. With that gate, the next load
onto one of those project dirs deletes the unpacked database of a server
still using it -- turning a registry glitch into real corruption. It fired:
the load that printed "cleared stale IDA database residue (5 file(s))"
was clearing files belonging to a live server, and reproduces on demand.

Ownership is now established from the process table, which cannot
silently lose a live process, instead of from the registry. Verified both
directions: with a live owner the files survive (and the second load fails
honestly, because IDA cannot open a database another process holds);
with no owner the residue is still cleared, so the original fix is intact.

Falls back to "assume owned" if psutil is unavailable -- refusing to clear
costs a reload, clearing wrongly costs the database.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant