Skip to content

Commit 1a67c41

Browse files
piastrysmfrench
authored andcommitted
CIFS: Fix use after free of file info structures
Currently the code assumes that if a file info entry belongs to lists of open file handles of an inode and a tcon then it has non-zero reference. The recent changes broke that assumption when putting the last reference of the file info. There may be a situation when a file is being deleted but nothing prevents another thread to reference it again and start using it. This happens because we do not hold the inode list lock while checking the number of references of the file info structure. Fix this by doing the proper locking when doing the check. Fixes: 487317c ("cifs: add spinlock for the openFileList to cifsInodeInfo") Fixes: cb24881 ("cifs: use cifsInodeInfo->open_file_lock while iterating to avoid a panic") Cc: Stable <[email protected]> Reviewed-by: Ronnie Sahlberg <[email protected]> Signed-off-by: Pavel Shilovsky <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent abe5707 commit 1a67c41

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

fs/cifs/file.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -405,10 +405,11 @@ void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, bool wait_oplock_handler)
405405
bool oplock_break_cancelled;
406406

407407
spin_lock(&tcon->open_file_lock);
408-
408+
spin_lock(&cifsi->open_file_lock);
409409
spin_lock(&cifs_file->file_info_lock);
410410
if (--cifs_file->count > 0) {
411411
spin_unlock(&cifs_file->file_info_lock);
412+
spin_unlock(&cifsi->open_file_lock);
412413
spin_unlock(&tcon->open_file_lock);
413414
return;
414415
}
@@ -421,9 +422,7 @@ void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, bool wait_oplock_handler)
421422
cifs_add_pending_open_locked(&fid, cifs_file->tlink, &open);
422423

423424
/* remove it from the lists */
424-
spin_lock(&cifsi->open_file_lock);
425425
list_del(&cifs_file->flist);
426-
spin_unlock(&cifsi->open_file_lock);
427426
list_del(&cifs_file->tlist);
428427
atomic_dec(&tcon->num_local_opens);
429428

@@ -440,6 +439,7 @@ void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, bool wait_oplock_handler)
440439
cifs_set_oplock_level(cifsi, 0);
441440
}
442441

442+
spin_unlock(&cifsi->open_file_lock);
443443
spin_unlock(&tcon->open_file_lock);
444444

445445
oplock_break_cancelled = wait_oplock_handler ?

0 commit comments

Comments
 (0)