F_RDLCK lock to FreeBSD NFS server fails to R/O target file

From: John <jwd_at_freebsd.org>
Date: Wed, 24 Aug 2011 21:28:42 +0000
Hi Fellow NFS'ers,

   I believe I have found the problem we've been having with read locks
while attaching to a FreeBSD NFS server.

   In sys/nlm/nlm_prot_impl.c, function nlm_get_vfs_state(), there is a call
to VOP_ACCESS() as follows:

        /*
         * Check cred.
         */
        NLM_DEBUG(3, "nlm_get_vfs_state(): Calling VOP_ACCESS(VWRITE) with cred->cr_uid=%d\n",cred->cr_uid);
        error = VOP_ACCESS(vs->vs_vp, VWRITE, cred, curthread);
        if (error) {
                NLM_DEBUG(3, "nlm_get_vfs_state(): caller_name = %s VOP_ACCESS() returns %d\n",
                host->nh_caller_name, error);
                goto out;
        }

  The file being accessed is read only to the user, and open()ed with
O_RDONLY. The lock being requested is for a read.

fd = open(filename, O_RDONLY, 0);
...

lblk.l_type  = F_RDLCK;
lblk.l_start = 0;
lblk.l_whence= SEEK_SET;
lblk.l_len   = 0;
lblk.l_pid   = 0;
rc = fcntl(fd, F_SETLK, &lblk);

   Running the above from a remote system, the lock call fails with
errno set to ENOLCK. Given  cred->cr_uid comes in as 227 which is
my uid on the remote system. Since the file is R/O to me, and the
VOP_ACCESS() is asking for VWRITE, it fails with errno 13, EACCES,
Permission denied.

   The above operations work correctly to some of our other
favorite big-name nfs vendors :-)

   Opinions on the "correct" way to fix this?

1. Since we're only asking for a read lock, why do we need to ask
   for VWRITE? I may not understand an underlying requirement for
   the VWRITE so please feel free to educate me if needed.

   Something like:  request == F_RDLCK ? VREAD : VWRITE
   (need to figure out where to get the request from in this context).

2. Attempt VWRITE, fallback to VREAD... seems off to me though.

3. Other?

   I appreciate any thoughts on this.

Thanks,
John

   While they might not follow style(9) completely, I've uploaded
my patch to nlm_prot.impl.c with the NLM_DEBUG() calls i've added.
I'd appreciate it if someone would consider committing them so
who ever debugs this file next will have them available.

http://people.freebsd.org/~jwd/nlm_prot_impl.c.patch
Received on Wed Aug 24 2011 - 19:28:42 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:17 UTC