Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 1215

kernel-2.6.18-238.el5.src.rpm

From: Dave Chinner <dchinner@redhat.com>
Date: Mon, 13 Sep 2010 06:01:36 -0400
Subject: [fs] xfs: fix missing untrusted inode lookup tag
Message-id: <1284357696-14857-1-git-send-email-dchinner@redhat.com>
Patchwork-id: 28217
O-Subject: [RHEL5.6 PATCH] xfs: fix missing untrusted inode lookup tag
Bugzilla: 607032
RH-Acked-by: Eric Sandeen <sandeen@redhat.com>
RH-Acked-by: Christoph Hellwig <chellwig@redhat.com>

Upstream commit: None - fixes a bug introduced during backporting.
RH BZ: 633178

When backporting upstream commit 7124fe0a5b619d65b739477b3b55a20bf805b06d
("xfs: validate untrusted inode numbers during lookup") , I missed
the fact that RHEL5 kernels do not have the same handle lookup path as
they do in RHEL6. Hence open-by-handle inodes were not being validated at
all, and as such passing or failing the stale handle test case was very
much down to timing of operations. Hence on some machines it would pass,
on some machines it would fail, and the xfs_dump code would almost never
fail.

Add the correct XFS_IGET_UNTRUSTED flag to the handle xfs_iget call and
ensure the correct errors are reported back to userspace/NFS when an
EINVAL is returned.

Signed-off-by: Dave Chinner <dchinner@redhat.com>

diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c
index 8f0586f..82d5664 100644
--- a/fs/xfs/linux-2.6/xfs_export.c
+++ b/fs/xfs/linux-2.6/xfs_export.c
@@ -156,8 +156,18 @@ xfs_fs_get_dentry(
 	 */
 	error = xfs_iget(mp, NULL, xfid->fid_ino, XFS_IGET_UNTRUSTED,
 					XFS_ILOCK_SHARED, &ip, 0);
-	if (error)
+	if (error) {
+		/*
+		 * EINVAL means the inode cluster doesn't exist anymore.
+		 * This implies the filehandle is stale, so we should
+		 * translate it here.
+		 * We don't use ESTALE directly down the chain to not
+		 * confuse applications using bulkstat that expect EINVAL.
+		 */
+		if (error == EINVAL)
+			error = ESTALE;
 		return ERR_PTR(-error);
+	}
 	if (!ip)
 		return ERR_PTR(-EIO) ;
 
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index f59330d..e76644f 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -231,9 +231,20 @@ xfs_vget_fsop_handlereq(
 	/*
 	 * Get the XFS inode, building a Linux inode to go with it.
 	 */
-	error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0);
-	if (error)
+	error = xfs_iget(mp, NULL, ino, XFS_IGET_UNTRUSTED,
+				XFS_ILOCK_SHARED, &ip, 0);
+	if (error) {
+		/*
+		 * EINVAL means the inode cluster doesn't exist anymore.
+		 * This implies the filehandle is stale, so we should
+		 * translate it here.
+		 * We don't use ENOENT directly down the chain to not
+		 * confuse applications using bulkstat that expect EINVAL.
+		 */
+		if (error == EINVAL)
+			error = ENOENT;
 		return error;
+	}
 	if (ip == NULL)
 		return XFS_ERROR(EIO);
 	if (ip->i_d.di_gen != igen) {