Skip to content

Commit e72b9dd

Browse files
author
Al Viro
committed
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: [email protected] Signed-off-by: Al Viro <[email protected]>
1 parent bcf0d9d commit e72b9dd

File tree

1 file changed

+10
-2
lines changed

1 file changed

+10
-2
lines changed

fs/ecryptfs/inode.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ static int ecryptfs_i_size_read(struct dentry *dentry, struct inode *inode)
319319
static struct dentry *ecryptfs_lookup_interpose(struct dentry *dentry,
320320
struct dentry *lower_dentry)
321321
{
322-
struct inode *inode, *lower_inode = d_inode(lower_dentry);
322+
struct inode *inode, *lower_inode;
323323
struct ecryptfs_dentry_info *dentry_info;
324324
struct vfsmount *lower_mnt;
325325
int rc = 0;
@@ -339,7 +339,15 @@ static struct dentry *ecryptfs_lookup_interpose(struct dentry *dentry,
339339
dentry_info->lower_path.mnt = lower_mnt;
340340
dentry_info->lower_path.dentry = lower_dentry;
341341

342-
if (d_really_is_negative(lower_dentry)) {
342+
/*
343+
* negative dentry can go positive under us here - its parent is not
344+
* locked. That's OK and that could happen just as we return from
345+
* ecryptfs_lookup() anyway. Just need to be careful and fetch
346+
* ->d_inode only once - it's not stable here.
347+
*/
348+
lower_inode = READ_ONCE(lower_dentry->d_inode);
349+
350+
if (!lower_inode) {
343351
/* We want to add because we couldn't find in lower */
344352
d_add(dentry, NULL);
345353
return NULL;

0 commit comments

Comments
 (0)