diff mbox

[RFC] affs_lookup: switch to d_splice_alias()

Message ID 20180513160341.GN30522@ZenIV.linux.org.uk (mailing list archive)
State New, archived
Headers show

Commit Message

Al Viro May 13, 2018, 4:03 p.m. UTC
Making something exportable takes more than providing ->s_export_ops.
In particular, ->lookup() *MUST* use d_splice_alias() instead of
d_add().

Reading Documentation/filesystems/nfs/Exporting would've been a good idea;
as it is, exporting AFFS is badly (and exploitably) broken.

Partially-Fixes: ed4433d72394 "fs/affs: make affs exportable"
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Comments

David Sterba May 21, 2018, 1:46 p.m. UTC | #1
On Sun, May 13, 2018 at 05:03:42PM +0100, Al Viro wrote:
> Making something exportable takes more than providing ->s_export_ops.
> In particular, ->lookup() *MUST* use d_splice_alias() instead of
> d_add().
> 
> Reading Documentation/filesystems/nfs/Exporting would've been a good idea;
> as it is, exporting AFFS is badly (and exploitably) broken.
> 
> Partially-Fixes: ed4433d72394 "fs/affs: make affs exportable"
> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Acked-by: David Sterba <dsterba@suse.com>
Fabian Frederick Oct. 29, 2018, 4:45 p.m. UTC | #2
> On 13 May 2018 at 18:03 Al Viro <viro@ZenIV.linux.org.uk> wrote:
> 
> 
> Making something exportable takes more than providing ->s_export_ops.
> In particular, ->lookup() *MUST* use d_splice_alias() instead of
> d_add().
> 
> Reading Documentation/filesystems/nfs/Exporting would've been a good idea;
> as it is, exporting AFFS is badly (and exploitably) broken.

Hi Al,

	Could you tell me where Affs is broken ? affs_get_parent() uses d_obtain_alias() and
your patch fixes the lookup. Do you suggest other updates or to mark nfs support experimental in AFFS or 
 something else ?

(btw, other export functions are
fh_to_dentry using generic_fh_to_dentry()
fh_to_parent using generic_fh_to_parent()
)

Regards,
Fabian
diff mbox

Patch

diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index 1ed0fa4c4d48..41c5749f4db7 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -201,6 +201,7 @@  affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
 	struct super_block *sb = dir->i_sb;
 	struct buffer_head *bh;
 	struct inode *inode = NULL;
+	struct dentry *res;
 
 	pr_debug("%s(\"%pd\")\n", __func__, dentry);
 
@@ -223,14 +224,12 @@  affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
 		}
 		affs_brelse(bh);
 		inode = affs_iget(sb, ino);
-		if (IS_ERR(inode)) {
-			affs_unlock_dir(dir);
-			return ERR_CAST(inode);
-		}
 	}
-	d_add(dentry, inode);
+	res = d_splice_alias(inode, dentry);
+	if (!IS_ERR_OR_NULL(res))
+		res->d_fsdata = dentry->d_fsdata;
 	affs_unlock_dir(dir);
-	return NULL;
+	return res;
 }
 
 int