mirror of
https://github.com/versity/scoutfs.git
synced 2026-02-07 11:10:44 +00:00
scoutfs: remove lock idr in free, not put
The idr entry that identifies a lock's position in the debugfs locks file is allocated early in the process of building up a lock. Today the idr entry is only destroyed in put_(), which is called later once reference counts are established. Errors before then just call free_() and can leave idrs around that reference freed memory. This always destroys the idr entry in free_(). We no longer leave idr entries around that reference freed memory. This fixes use after free while walking the debugfs file which can hit in scoutfs/006 which uses the locks file. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
@@ -259,6 +259,13 @@ static void free_scoutfs_lock(struct scoutfs_lock *lock)
|
||||
if (lock) {
|
||||
linfo = SCOUTFS_SB(lock->sb)->lock_info;
|
||||
|
||||
if (lock->debug_locks_id) {
|
||||
spin_lock(&linfo->lock);
|
||||
idr_remove(&linfo->debug_locks_idr,
|
||||
lock->debug_locks_id);
|
||||
spin_unlock(&linfo->lock);
|
||||
}
|
||||
|
||||
scoutfs_inc_counter(lock->sb, lock_free);
|
||||
ocfs2_lock_res_free(&lock->lockres);
|
||||
scoutfs_key_free(lock->sb, lock->start);
|
||||
@@ -288,9 +295,6 @@ static void put_scoutfs_lock(struct super_block *sb, struct scoutfs_lock *lock)
|
||||
RB_CLEAR_NODE(&lock->range_node);
|
||||
}
|
||||
list_del(&lock->lru_entry);
|
||||
if (lock->debug_locks_id)
|
||||
idr_remove(&linfo->debug_locks_idr,
|
||||
lock->debug_locks_id);
|
||||
spin_unlock(&linfo->lock);
|
||||
ocfs2_simple_drop_lockres(&linfo->dlmglue,
|
||||
&lock->lockres);
|
||||
|
||||
Reference in New Issue
Block a user