From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from zeniv.linux.org.uk ([195.92.253.2]:36188 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751584AbeEMQAl (ORCPT ); Sun, 13 May 2018 12:00:41 -0400 Date: Sun, 13 May 2018 17:00:40 +0100 From: Al Viro To: linux-fsdevel@vger.kernel.org Cc: David Sterba Subject: [RFC][PATCH] affs_lookup(): close a race with affs_remove_link() Message-ID: <20180513160040.GM30522@ZenIV.linux.org.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Sender: linux-fsdevel-owner@vger.kernel.org List-ID: [#fixes unless somebody yells; -stable fodder and yes, it _is_ that old - all way back to 2001] we unlock the directory hash too early - if we are looking at secondary link and primary (in another directory) gets removed just as we unlock, we could have the old primary moved in place of the secondary, leaving us to look into freed entry (and leaving our dentry with ->d_fsdata pointing to a freed entry). Cc: stable@vger.kernel.org # 2.4.4+ Signed-off-by: Al Viro diff --git a/fs/affs/namei.c b/fs/affs/namei.c index d8aa0ae3d037..1ed0fa4c4d48 100644 --- a/fs/affs/namei.c +++ b/fs/affs/namei.c @@ -206,9 +206,10 @@ affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) affs_lock_dir(dir); bh = affs_find_entry(dir, dentry); - affs_unlock_dir(dir); - if (IS_ERR(bh)) + if (IS_ERR(bh)) { + affs_unlock_dir(dir); return ERR_CAST(bh); + } if (bh) { u32 ino = bh->b_blocknr; @@ -222,10 +223,13 @@ affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) } affs_brelse(bh); inode = affs_iget(sb, ino); - if (IS_ERR(inode)) + if (IS_ERR(inode)) { + affs_unlock_dir(dir); return ERR_CAST(inode); + } } d_add(dentry, inode); + affs_unlock_dir(dir); return NULL; }