bug-fileutils
[Top][All Lists]
Advanced

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

Re: EMC Celerra: opendir bug? [Re: in ls.c, should check errno after rea


From: Mike Coleman
Subject: Re: EMC Celerra: opendir bug? [Re: in ls.c, should check errno after readdir
Date: 27 Aug 2002 22:53:16 -0500
User-agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/21.2

Jim Meyering <address@hidden> writes:
> Mike Coleman <address@hidden> wrote:
> > In ls.c, errno should be checked after a NULL result from readdir, to see if
> > there was an error.  It may be that in a "normal" posix system, no error can
> > happen here, but my NAS box (an EMC Celerra) is reporting EACCES here, so a
> > defensive check, rather than ignoring the error, would be helpful.
> >
> > I suppose this applies to all readdir's.
> 
> Thanks for the report.
> IMHO, this is not a bug, and no program should check errno after readdir.
> 
> Does EMC's opendir succeed for a directory even though one has
> insufficient permission?  POSIX requires that opendir fail with EACCES if
> 
>   ``Search permission is denied for the component of the path
>     prefix of dirname or read permission is denied for dirname.''
> 
> If so, I suggest that you file a bug report with EMC.


With respect to POSIX, this sounds right to me.

Unfortunately, there is an additional problem.  RFC 1813 (NFS v3) states
pretty explicitly that NFS servers are allowed to deny access at any time to a
file or directory, and for reasons other than the Unix permissions info.  Here
are some excerpts:

   Servers can revoke the access provided by a file handle at any time.  If
   the file handle passed in a call refers to a file system object that no
   longer exists on the server or access for that file handle has been
   revoked, the error, NFS3ERR_STALE, should be returned.

   The results of this procedure [ACCESS] are necessarily advisory in nature.
   That is, a return status of NFS3_OK and the appropriate bit set in the bit
   mask does not imply that such access will be allowed to the file system
   object in the future, as access rights can be revoked by the server at any
   time.

   In general, it is not sufficient for the client to attempt to deduce access
   permissions by inspecting the uid, gid, and mode fields in the file
   attributes, since the server may perform uid or gid mapping or enforce
   additional access control restrictions. It is also possible that the NFS
   version 3 protocol server may not be in the same ID space as the NFS
   version 3 protocol client. In these cases (and perhaps others), the NFS
   version 3 protocol client can not reliably perform an access check with
   only current file attributes.

   The information returned by the server in response to an ACCESS call is not
   permanent. It was correct at the exact time that the server performed the
   checks, but not necessarily afterwards. The server can revoke access
   permission at any time.

Given this, it's almost a certainty that the NFS calls necessary to carry out
a readdir(3) might fail.  (The only way I can see to avoid this would be to
atomically read all of the dirents into the kernel during the opendir(3) call,
which doesn't sound like a good idea.)  I'm not crazy about the semantics
here, but it would appear that EMC is not violating this RFC.

The issue with opendir(3) is a little more subtle.  It turns out that Linux
itself is allowing this call to succeed without bothering to do an ACCESS call
to the EMC NFS server.  It is succeeding because Linux is inferring that it
would based on the Unix permissions (arguably a Linux bug).  The EMC box
doesn't get a chance to deny until it is sent the first READDIR, which happens
when the first readdir(3) is done.

Given the RFC, it seems like having readdir(3) return EACCES when the NFS
server suddenly denies access is about the best thing it could do.  I think
this is what Linux is doing.

Given this reality, it seems pretty bad to have ls ignore error returns from
readdir(3) (or any other I/O call).

Mike




reply via email to

[Prev in Thread] Current Thread [Next in Thread]