[PATCH v2 0/3] Support opening a symlink with O_PATH | O_NOFOLLOW

Ken Brown kbrown@cornell.edu
Mon Jan 13 16:53:00 GMT 2020


On 1/13/2020 10:28 AM, Corinna Vinschen wrote:
> Hi Ken,
> 
> On Dec 29 17:56, Ken Brown wrote:
>> Currently, opening a symlink with O_NOFOLLOW fails with ELOOP.
>> Following Linux, the first patch in this series allows the call to
>> succeed if O_PATH is also specified.
>>
>> According to the Linux man page for 'open', the file descriptor
>> returned by the call should be usable as the dirfd argument in calls
>> to fstatat and readlinkat with an empty pathname, to have
>> the calls operate on the symbolic link.  The second and third patches
>> achieve this.  For fstatat, we do this by adding support
>> for the AT_EMPTY_PATH flag.
>>
>> Note: The man page mentions fchownat and linkat also.  linkat already
>> supports the AT_EMPTY_PATH flag, so nothing needs to be done.  But I
>> don't understand how this could work for fchownat, because fchown
>> fails with EBADF if its fd argument was opened with O_PATH.  So I
>> haven't touched fchownat.
> 
> It was never supposed to work that way.  We can make fchownat work
> with AT_EMPTY_PATH, but using it on a file opened with O_PATH
> contradicts the Linux open(2) man page, afaics:
> 
>   O_PATH (since Linux 2.6.39)
>    Obtain a file descriptor that can be used for two  purposes:  to
>    indicate a location in the filesystem tree and to perform opera‐
>    tions that act purely at the file descriptor  level.   The  file
>    itself  is not opened, and other file operations (e.g., read(2),
>    write(2), fchmod(2), fchown(2), fgetxattr(2), ioctl(2), mmap(2))
>                         ^^^^^^^^^
>    fail with the error EBADF.
>    ^^^^^^^^^           ^^^^^
> 
> That'd from the current F31 man pages.
> 
>> Am I missing something?
> 
> Good question.  Let me ask in return, did *I* now miss something?

I don't think so.  I think we agree, although maybe I didn't express myself 
clearly enough for that to be obvious.  What confused me was the following 
paragraph further down in the open(2) man page (still discussing O_PATH):

   If pathname is a symbolic link and the O_NOFOLLOW flag is also
   specified, then the call returns a file descriptor referring
   to the symbolic link.  This file descriptor can be used as the
   dirfd argument in calls to fchownat(2), fstatat(2), linkat(2),
                              ^^^^^^^^^^^
   and readlinkat(2) with an empty pathname to have the calls
   operate on the symbolic link.

I don't know why they include fchownat here, since the resulting call would fail 
with EBADF.  So I didn't implement that in my patch series.

Ken


More information about the Cygwin-patches mailing list