Re: [PATCH] nfs: don't allow nfs_find_actor to match inodes of the wrong type

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Jul 31, 2013 at 7:46 PM, Jeff Layton <jlayton@xxxxxxxxxx> wrote:
> On Wed, 31 Jul 2013 18:00:51 -0500
> Quentin Barnes <qbarnes@xxxxxxxxx> wrote:
>
>> > Quite frankly, all I care about in a situation like this is that the
>> > client doesn't Oops.
>>
>> Certainly, and his patch does do that, but it's also pointing out
>> there's another bug running around.  And once you fix that bug, the
>> original patch is no longer needed.
>>
>> > If a server is really this utterly broken, then there is no way we can
>> > fix it on the client, and we're not even going to try.
>>
>> Of course.  But you also don't want to unnecessarily leave the
>> client with an invalid inode that's not properly flagged and
>> possibly leave another bug unfixed.
>>
>> Here is a example patch that I feel better addresses the problem:
>>
>>
>> commit 2d6b411eea04ae4398707b584b8d9e552606aaf7
>> Author: Quentin Barnes <qbarnes@xxxxxxxxxxxxx>
>> Date:   Wed Jul 31 17:50:35 2013 -0500
>>
>>     Have nfs_refresh_inode_locked() ensure that it doesn't return without
>>     flagging invalid inodes (ones that don't match its fattr type).
>>
>>     nfs_refresh_inode() already does this, so we need to check the return
>>     status from nfs_check_inode_attributes() before returning from
>>     nfs_refresh_inode_locked().
>>
>>     Once this hole is plugged, there will be no invalid inode references
>>     returned by nfs_fhget(), so no need to check in nfs_find_actor().
>>
>> diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
>> index af6e806..d2263a5 100644
>> --- a/fs/nfs/inode.c
>> +++ b/fs/nfs/inode.c
>> @@ -244,8 +244,6 @@ nfs_find_actor(struct inode *inode, void *opaque)
>>
>>       if (NFS_FILEID(inode) != fattr->fileid)
>>               return 0;
>> -     if ((S_IFMT & inode->i_mode) != (S_IFMT & fattr->mode))
>> -             return 0;
>>       if (nfs_compare_fh(NFS_FH(inode), fh))
>>               return 0;
>>       if (is_bad_inode(inode) || NFS_STALE(inode))
>> @@ -1269,9 +1267,16 @@ static int nfs_inode_attrs_need_update(const struct inode *inode, const struct n
>>
>>  static int nfs_refresh_inode_locked(struct inode *inode, struct nfs_fattr *fattr)
>>  {
>> +     int     status;
>> +
>>       if (nfs_inode_attrs_need_update(inode, fattr))
>>               return nfs_update_inode(inode, fattr);
>> -     return nfs_check_inode_attributes(inode, fattr);
>> +
>> +     status = nfs_check_inode_attributes(inode, fattr);
>> +     if (status)
>> +             nfs_invalidate_inode(inode);
>> +
>> +     return status;
>>  }
>>
>>  /**
>
> I don't think that's going to fix the problem.
>
> The issue is that the i_fops are set when the inode is in I_NEW state,
> and are never changed. An inode is only I_NEW when it's first created.
> In this case, we did an atomic open against a filename and got back
> attributes that trick the code into matching the new dentry up with an
> inode that we previously found to be a directory.

Oh, yes!  The original reported mentioned an atomic open.  We should
look at it from that NFSv4 perspective.

(I know I tend to inadvertently focus too much on the NFSv3 paths
since I know those best.  Sigh.)

> The patch above doesn't address that.

I disagree.

Let's take a look at it from the NFSv4 angle --

The NFSv4 atomic open call path is:
  nfs4_atomic_open()->nfs4_do_open()->_nfs4_do_open()

In _nfs4_do_open(), it calls nfs4_do_setattr() which fills in an
fattr structure then calls nfs_post_op_update_inode() with it to
update the inode.  Then we call nfs_post_op_update_inode()->
nfs_post_op_update_inode_locked()->nfs_refresh_inode_locked().

So, yes, I think even in Benny's case, fixing nfs_refresh_inode_locked()
to invalidate an inode when nfs_check_inode_attributes() catches that
an NFS server had pulled a switcheroo (dir to file with same fh), the
approach above would have caught it when it happened.

> It just adds an extra cache
> invalidation, which won't help this case. The ops are still set the
> same way and the teardown of the atomic_open will still end up hitting
> the panic.

It would help me if you could explain how flagging the inode as
invalid doesn't help here.  If that's the case, then other bugs
might be running around.

> --
> Jeff Layton <jlayton@xxxxxxxxxx>
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux