From: Vitaliy Gusev <gusev.vitaliy@nexenta.com>
To: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: linux-nfs@vger.kernel.org, Al Viro <viro@zeniv.linux.org.uk>,
linux-fsdevel <linux-fsdevel@vger.kernel.org>
Subject: Re: [PATCH] nfs4: Fix NULL dereference at d_alloc_and_lookup()
Date: Wed, 23 Mar 2011 12:27:02 +0300 [thread overview]
Message-ID: <4D89BCE6.3040707@nexenta.com> (raw)
In-Reply-To: <1300838379.22796.35.camel@lade.trondhjem.org>
On 03/23/2011 02:59 AM, Trond Myklebust wrote:
> On Wed, 2011-03-23 at 01:58 +0300, Vitaliy Gusev wrote:
>> On Tue, 2011-03-22 at 17:52 -0400, Trond Myklebust wrote:
>>> On Wed, 2011-03-23 at 00:40 +0300, Vitaliy Gusev wrote:
>>>> From: Gusev Vitaliy<gusev.vitaliy@nexenta.com>
>>>>
>>>> d_alloc_and_lookup() calls i_op->lookup method due to
>>>> rootfh changes his fsid.
>>>>
>>>> During mount i_op of NFS root inode is set to
>>>> nfs_mountpoint_inode_operations, if rpc_ops->getroot()
>>>> and rpc_ops->getattr() return different fsid.
>>>
>>> That is a server bug! Why are you trying to "fix" that on the client
>>> instead of telling the user that their server deserves to be burned
>>> behind the shed?
>>>
>>
>> Because nfs_update_inode() does it with success and pleasure:
>>
>> if (S_ISDIR(inode->i_mode)&& (fattr->valid& NFS_ATTR_FATTR_FSID)&&
>> !nfs_fsid_equal(&server->fsid,&fattr->fsid)&&
>> !IS_AUTOMOUNT(inode))
>> server->fsid = fattr->fsid;
>>
>> And what are the reasons to tell to user about broken servers during
>> mount, but do not tell about it after mount ?
>
> Sigh... That is a valid point.
>
> Looking at the Linux NFS server, I see that it has 3 different ways to
> derive a fsid: only two are guaranteed to survive a reboot. I believe
> that is probably why we added the above code to nfs_update_inode().
>
> Looking now at the uses of nfs4_get_root(), it looks as if all the users
> have compared the original fsid to the super block fsid prior to getting
> here, and so we know (hope) that the directory that was obtained with
> this filehandle did at one point match. If that is always the case, then
> we should be safe w.r.t. mistaking this for a server-side mountpoint.
> Since a referral is supposed to give us an error when we try to get the
> directory attributes,
Check on referral at nfs4_get_rootfh():
if (fsinfo.fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) {
printk(KERN_ERR "nfs4_get_rootfh:"
" getroot obtained referral\n");
ret = -EREMOTE;
goto out;
}
is vain and can be removed. That path never sets NFS_ATTR_FATTR_V4_REFERRAL.
then we know this isn't pointing to a referral.
Check
(A)
if (mntroot->d_inode->i_op !=
NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
dput(mntroot);
error = -ESTALE;
goto error_splat_super;
}
was initially added by commit 4c1fe2f7 and now is not required because:
1. This patch fixes of changing i_op at nfs_fhget(). So
nfs4_get_root() always will return i_op == dir_inode_ops.
2. commit 4c1fe2f7 fixed BUG_ON at nfs_follow_mountpoint(). Now there
is no BUG_ON. It was replaced with ESTALE by commit 44d5759d
So only one thing that does check (A) - it fixes changing fsid
behaviour for NFSv2,NFSv3 protocol - nfs_xdev_mount(). In other places
it can be removed:
*** fs/nfs/super.c:
nfs_xdev_mount[2483] if (mntroot->d_inode->i_op !=
NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
nfs4_xdev_mount[3066] if (mntroot->d_inode->i_op !=
NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
nfs4_remote_referral_mount[3153] if (mntroot->d_inode->i_op !=
NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
>
> OK, I'll take this patch...
WARNING: multiple messages have this Message-ID (diff)
From: Vitaliy Gusev <gusev.vitaliy-x4E8uuA0+mFBDgjK7y7TUQ@public.gmane.org>
To: Trond Myklebust
<Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA@public.gmane.org>
Cc: linux-nfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Al Viro <viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn@public.gmane.org>,
linux-fsdevel
<linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
Subject: Re: [PATCH] nfs4: Fix NULL dereference at d_alloc_and_lookup()
Date: Wed, 23 Mar 2011 12:27:02 +0300 [thread overview]
Message-ID: <4D89BCE6.3040707@nexenta.com> (raw)
In-Reply-To: <1300838379.22796.35.camel-SyLVLa/KEI9HwK5hSS5vWB2eb7JE58TQ@public.gmane.org>
On 03/23/2011 02:59 AM, Trond Myklebust wrote:
> On Wed, 2011-03-23 at 01:58 +0300, Vitaliy Gusev wrote:
>> On Tue, 2011-03-22 at 17:52 -0400, Trond Myklebust wrote:
>>> On Wed, 2011-03-23 at 00:40 +0300, Vitaliy Gusev wrote:
>>>> From: Gusev Vitaliy<gusev.vitaliy-x4E8uuA0+mFBDgjK7y7TUQ@public.gmane.org>
>>>>
>>>> d_alloc_and_lookup() calls i_op->lookup method due to
>>>> rootfh changes his fsid.
>>>>
>>>> During mount i_op of NFS root inode is set to
>>>> nfs_mountpoint_inode_operations, if rpc_ops->getroot()
>>>> and rpc_ops->getattr() return different fsid.
>>>
>>> That is a server bug! Why are you trying to "fix" that on the client
>>> instead of telling the user that their server deserves to be burned
>>> behind the shed?
>>>
>>
>> Because nfs_update_inode() does it with success and pleasure:
>>
>> if (S_ISDIR(inode->i_mode)&& (fattr->valid& NFS_ATTR_FATTR_FSID)&&
>> !nfs_fsid_equal(&server->fsid,&fattr->fsid)&&
>> !IS_AUTOMOUNT(inode))
>> server->fsid = fattr->fsid;
>>
>> And what are the reasons to tell to user about broken servers during
>> mount, but do not tell about it after mount ?
>
> Sigh... That is a valid point.
>
> Looking at the Linux NFS server, I see that it has 3 different ways to
> derive a fsid: only two are guaranteed to survive a reboot. I believe
> that is probably why we added the above code to nfs_update_inode().
>
> Looking now at the uses of nfs4_get_root(), it looks as if all the users
> have compared the original fsid to the super block fsid prior to getting
> here, and so we know (hope) that the directory that was obtained with
> this filehandle did at one point match. If that is always the case, then
> we should be safe w.r.t. mistaking this for a server-side mountpoint.
> Since a referral is supposed to give us an error when we try to get the
> directory attributes,
Check on referral at nfs4_get_rootfh():
if (fsinfo.fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) {
printk(KERN_ERR "nfs4_get_rootfh:"
" getroot obtained referral\n");
ret = -EREMOTE;
goto out;
}
is vain and can be removed. That path never sets NFS_ATTR_FATTR_V4_REFERRAL.
then we know this isn't pointing to a referral.
Check
(A)
if (mntroot->d_inode->i_op !=
NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
dput(mntroot);
error = -ESTALE;
goto error_splat_super;
}
was initially added by commit 4c1fe2f7 and now is not required because:
1. This patch fixes of changing i_op at nfs_fhget(). So
nfs4_get_root() always will return i_op == dir_inode_ops.
2. commit 4c1fe2f7 fixed BUG_ON at nfs_follow_mountpoint(). Now there
is no BUG_ON. It was replaced with ESTALE by commit 44d5759d
So only one thing that does check (A) - it fixes changing fsid
behaviour for NFSv2,NFSv3 protocol - nfs_xdev_mount(). In other places
it can be removed:
*** fs/nfs/super.c:
nfs_xdev_mount[2483] if (mntroot->d_inode->i_op !=
NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
nfs4_xdev_mount[3066] if (mntroot->d_inode->i_op !=
NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
nfs4_remote_referral_mount[3153] if (mntroot->d_inode->i_op !=
NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) {
>
> OK, I'll take this patch...
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2011-03-23 9:42 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-22 21:40 [PATCH] nfs4: Fix NULL dereference at d_alloc_and_lookup() Vitaliy Gusev
2011-03-22 21:40 ` Vitaliy Gusev
2011-03-22 21:52 ` Trond Myklebust
2011-03-22 21:52 ` Trond Myklebust
2011-03-22 22:58 ` Vitaliy Gusev
2011-03-22 22:58 ` Vitaliy Gusev
2011-03-22 23:59 ` Trond Myklebust
2011-03-22 23:59 ` Trond Myklebust
2011-03-23 9:27 ` Vitaliy Gusev [this message]
2011-03-23 9:27 ` Vitaliy Gusev
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4D89BCE6.3040707@nexenta.com \
--to=gusev.vitaliy@nexenta.com \
--cc=Trond.Myklebust@netapp.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.