Skip to content

Fix locking and a double free in fsops rename and unlink#615

Open
matejk wants to merge 2 commits into
LinearTapeFileSystem:mainfrom
matejk:fix/fsops-locking
Open

Fix locking and a double free in fsops rename and unlink#615
matejk wants to merge 2 commits into
LinearTapeFileSystem:mainfrom
matejk:fix/fsops-locking

Conversation

@matejk

@matejk matejk commented Jun 12, 2026

Copy link
Copy Markdown

Two commits:

  • Releases of unheld meta_lock: in ltfs_fsops_rename, the directory WORM checks ran before todir's meta_lock was acquired but their error path released it (whenever todir != fromdir); ltfs_fsops_unlink had the same defect for parent->meta_lock on its WORM and non-empty-directory error paths. Releasing an unheld rwlock is undefined behaviour and can corrupt the lock state. The checks now run with the locks held; lock ordering is preserved.
  • Double free on a late rename failure: after the destination name buffers were assigned to fromdentry, a later failure freed them via out_free and left dangling pointers that were freed again when the dentry is disposed. Ownership is now cleared from the locals when it moves.

@vandelvan vandelvan requested review from XV02, madjesc and syaoraang June 12, 2026 20:55
matejk added 2 commits June 17, 2026 22:06
ltfs_fsops_rename ran the directory WORM checks right after lookup,
before todir's meta_lock was acquired, then jumped to out_release,
which releases todir->meta_lock via fs_release_dentry_unlocked()
whenever todir != fromdir. Renaming into or out of a WORM directory
therefore unlocked a lock that was never held, and the immutable/
appendonly fields were read without meta_lock. Move the check to after
both directory meta_locks are held, mirroring the existing
source/target entry WORM check.

ltfs_fsops_unlink had the same defect: the shared out: path releases
parent->meta_lock, but the lock was only acquired after the WORM and
non-empty-directory checks, so those error paths unlocked a lock they
never held. Acquire parent->meta_lock once before the checks; lock
ordering is preserved (parent contents before parent meta before child
meta).

Releasing an unheld rwlock is undefined behaviour and can corrupt the
lock state.
After the destination name buffers are assigned to fromdentry, a later
failure (e.g. fs_add_key_to_hash_table) reached out_free, which freed
those same buffers because ret < 0 — leaving fromdentry with dangling
name/platform_safe_name pointers that are freed again when the dentry is
disposed. Clear the locals once ownership moves to fromdentry.
@matejk matejk force-pushed the fix/fsops-locking branch from 9372f75 to bbdf041 Compare June 17, 2026 20:35
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