ecryptfs_lookup_interpose(): lower_dentry->d_inode is not stable
lower_dentry can't go from positive to negative (we have it pinned), but it *can* go from negative to positive. So fetching ->d_inode into a local variable, doing a blocking allocation, checking that now ->d_inode is non-NULL and feeding the value we'd fetched earlier to a function that won't accept NULL is not a good idea. Cc: stable@vger.kernel.org Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Родитель
bcf0d9d4b7
Коммит
e72b9dd6a5
|
@ -319,7 +319,7 @@ static int ecryptfs_i_size_read(struct dentry *dentry, struct inode *inode)
|
|||
static struct dentry *ecryptfs_lookup_interpose(struct dentry *dentry,
|
||||
struct dentry *lower_dentry)
|
||||
{
|
||||
struct inode *inode, *lower_inode = d_inode(lower_dentry);
|
||||
struct inode *inode, *lower_inode;
|
||||
struct ecryptfs_dentry_info *dentry_info;
|
||||
struct vfsmount *lower_mnt;
|
||||
int rc = 0;
|
||||
|
@ -339,7 +339,15 @@ static struct dentry *ecryptfs_lookup_interpose(struct dentry *dentry,
|
|||
dentry_info->lower_path.mnt = lower_mnt;
|
||||
dentry_info->lower_path.dentry = lower_dentry;
|
||||
|
||||
if (d_really_is_negative(lower_dentry)) {
|
||||
/*
|
||||
* negative dentry can go positive under us here - its parent is not
|
||||
* locked. That's OK and that could happen just as we return from
|
||||
* ecryptfs_lookup() anyway. Just need to be careful and fetch
|
||||
* ->d_inode only once - it's not stable here.
|
||||
*/
|
||||
lower_inode = READ_ONCE(lower_dentry->d_inode);
|
||||
|
||||
if (!lower_inode) {
|
||||
/* We want to add because we couldn't find in lower */
|
||||
d_add(dentry, NULL);
|
||||
return NULL;
|
||||
|
|
Загрузка…
Ссылка в новой задаче