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

Eric Blake eblake@redhat.com
Mon Jan 13 17:24:00 GMT 2020

On 1/13/20 10:53 AM, Ken Brown wrote:
> 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.

>>    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.
>>     ^^^^^^^^^           ^^^^^

On BSD systems, you are able to run lchmod to change permissions on a 
symlink (with effect on who is able to follow that symlink during 
pathname resolution); Linux does not support that, and POSIX does not 
mandate support for that, so fchmodat() is allowed to fail on symlinks 
even while fchownat() is required to work on symlinks.

>> 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.

I'm not sure if the question here is about fchownat() (where you CAN 
change owner of a symlink on Linux, same as with lchown()) or about 
fchmodat() (where you would attempt to change permissions of a symlink, 
as on BSD, but where Linux lacks lchmod()).

Another wrinkle is that for the longest time, the Linux kernel did not 
make it possible to correctly implement fchmodat(AT_SYMLINK_NOFOLLOW); 
it is only with the recent introduction of the fchmodat2() syscall that 
this has become possible (https://patchwork.kernel.org/patch/9596301/)

Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org

More information about the Cygwin-patches mailing list