diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-01-02 13:28:57 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-01-03 09:37:11 -0500 |
commit | e9cc6c234bfe414ef36f484e3ad8be621854c440 (patch) | |
tree | 8f1b6bf16c9f6b340fa398d39f55bcc51be4f05e | |
parent | b8c9a18712f7b617fda66d878ce3759c9e575ba0 (diff) |
NFS: Fix a possible Oops in fs/nfs/super.c
Sigh... commit 4584f520e1f773082ef44ff4f8969a5d992b16ec (NFS: Fix NFS
mountpoint crossing...) had a slight flaw: server can be NULL if sget()
returned an existing superblock.
Fix the fix by dereferencing s->s_fs_info.
Thanks to Coverity/Adrian Bunk and Frank Filz for spotting the bug.
(See http://bugzilla.kernel.org/show_bug.cgi?id=9647)
Also add in the same namespace Oops fix for NFSv4 in both the mountpoint
crossing case, and the referral case.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/super.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index ea929207f274..0b0c72a072ff 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -1475,7 +1475,7 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, | |||
1475 | error = PTR_ERR(mntroot); | 1475 | error = PTR_ERR(mntroot); |
1476 | goto error_splat_super; | 1476 | goto error_splat_super; |
1477 | } | 1477 | } |
1478 | if (mntroot->d_inode->i_op != server->nfs_client->rpc_ops->dir_inode_ops) { | 1478 | if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) { |
1479 | dput(mntroot); | 1479 | dput(mntroot); |
1480 | error = -ESTALE; | 1480 | error = -ESTALE; |
1481 | goto error_splat_super; | 1481 | goto error_splat_super; |
@@ -1826,6 +1826,11 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags, | |||
1826 | error = PTR_ERR(mntroot); | 1826 | error = PTR_ERR(mntroot); |
1827 | goto error_splat_super; | 1827 | goto error_splat_super; |
1828 | } | 1828 | } |
1829 | if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) { | ||
1830 | dput(mntroot); | ||
1831 | error = -ESTALE; | ||
1832 | goto error_splat_super; | ||
1833 | } | ||
1829 | 1834 | ||
1830 | s->s_flags |= MS_ACTIVE; | 1835 | s->s_flags |= MS_ACTIVE; |
1831 | mnt->mnt_sb = s; | 1836 | mnt->mnt_sb = s; |
@@ -1900,6 +1905,11 @@ static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags, | |||
1900 | error = PTR_ERR(mntroot); | 1905 | error = PTR_ERR(mntroot); |
1901 | goto error_splat_super; | 1906 | goto error_splat_super; |
1902 | } | 1907 | } |
1908 | if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) { | ||
1909 | dput(mntroot); | ||
1910 | error = -ESTALE; | ||
1911 | goto error_splat_super; | ||
1912 | } | ||
1903 | 1913 | ||
1904 | s->s_flags |= MS_ACTIVE; | 1914 | s->s_flags |= MS_ACTIVE; |
1905 | mnt->mnt_sb = s; | 1915 | mnt->mnt_sb = s; |