[PATCH v7 0/4] ntfs: serialize attribute-list access
Hyunchul Lee <[email protected]>
| Newsgroups | dev.linux.lists.ntfs,org.kernel.vger.stable |
|---|---|
| Message-ID | <[email protected]> |
ntfs_external_attr_find() walks base_ni->attr_list using raw attr_list_entry pointers stored in ctx->al_entry. Because other paths can replace base_ni->attr_list and free the old buffer while a lookup still holds one of those cursors, a concurrent attribute-list mutation can turn a saved cursor into a stale or freed pointer. Reported in: https://lore.kernel.org/all/[email protected]/ This series fixes that hazard by replacing the raw ctx->al_entry pointer with restartable, generation-checked locators, and by adding locks that serialize attribute-list buffer replacement and on-disk persistence so concurrent mutations cannot corrupt state or double-free memory. The four patches are: 1. ntfs: replace raw ctx->al_entry with restartable attr-list locators 2. ntfs: protect attribute-list buffer replacement with attr_list_persist_lock 3. ntfs: protect attribute-list creation/teardown with attr_list_persist_lock 4. ntfs: protect mapping-pairs attr-list updates with attr_list_persist_lock What changes ------------ Instead of a raw struct attr_list_entry *, the search context now carries three value-only locators: - al_cursor -- where ntfs_external_attr_find() resumes enumeration; invalidated on generation mismatch. - al_insert -- insertion point captured on -ENOENT lookups. - al_exact -- immutable identity snapshot (type, lowest_vcn, mft_reference, instance, name length) used by writers to re-locate the same ALE after a buffer replacement. The inode gains attr_list_lock, an rwsem that protects the live buffer, its size and generation, and in-place ALE changes. Readers hold it only while dereferencing the buffer; writers hold it while replacing the buffer or changing an ALE, then increment the generation. Pointers into the buffer never survive an unlock, and the rwsem is dropped before persistence or an operation that can take runlist.lock or extent_lock. attr_list_persist_lock is a non-recursive mutex that serializes a mutation through persistence and rollback, including list creation and teardown. ntfs_attrlist_update_locked() writes the live buffer without attr_list_lock, so the caller holds this mutex from mutation through the write. It also stabilizes the buffer while attaching extents. When both locks are needed, take attr_list_persist_lock first. Creation owns the mutex itself, so callers must create first and then restart; re-entrant teardown uses persist_locked instead of recursively acquiring it. --- * Changes in v7: * Patch 3: serialize non-$ATTRIBUTE_LIST removal with concurrent attribute-list creation. * Patch 3: initialize successful removal results and release attr_list_persist_lock on every early creation error. * Changes in v6: * Patch 2: initialize new_al before an early error path can reach its cleanup, fixing an x86_64 allmodconfig Clang build warning. * Changes in v5: * Patch 3: keep each in-place ALE update and its persist in one transaction. This fixes the Patch 2 review: a record move could update an ALE while persistence copied the same buffer. * Patch 3: serialize attribute-list creation, teardown, and extent attachment. * Patch 4: acquire the mutex unconditionally for mapping-pairs updates to close the attribute-list creation TOCTOU; drop it before creating a missing list and restart afterward to avoid self-deadlock. * Changes in v4: * Patch 1: fix attr-list lock/unlock and uninitialized locator on the AT_END path * Patch 2: hold attr_list_persist_lock around all ntfs_attrlist_update() callers and recheck the attribute-list state after locking * Patch 4: avoid self-deadlock rebuilding $ATTRIBUTE_LIST's own mapping pairs * Changes in v3: * Patch 1: fix $ATTRIBUTE_LIST extent double-delivery during mapping-pairs rebuild (xfstests generic/040) * Patch 3: fix self-deadlock on attr_list_persist_lock during attr-list rebuild (xfstests generic/040) * Changes in v2: * add Fixes tags * add Reported-by and Tested-by tags Co-authored-by: Copilot <[email protected]> --- Hyunchul Lee (4): ntfs: replace raw ctx->al_entry with restartable attr-list locators ntfs: protect attribute-list buffer replacement with attr_list_persist_lock ntfs: protect attribute-list creation/teardown with attr_list_persist_lock ntfs: protect mapping-pairs attr-list updates with attr_list_persist_lock fs/ntfs/attrib.c | 568 ++++++++++++++++++++++++++++++++++++++++++++--------- fs/ntfs/attrib.h | 48 ++++- fs/ntfs/attrlist.c | 181 +++++++++++++---- fs/ntfs/attrlist.h | 3 +- fs/ntfs/index.c | 26 ++- fs/ntfs/inode.c | 116 ++++++++--- fs/ntfs/inode.h | 10 + fs/ntfs/namei.c | 2 +- fs/ntfs/super.c | 2 +- 9 files changed, 795 insertions(+), 161 deletions(-) --- base-commit: 5c244a0e9ca95468f4c2087b2c9269825429a13f change-id: 20260727-topic-attr-list-lock-v6-f1a909e3c859 Best regards, -- Thanks, Hyunchul