Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 04 Sep 2015 14:09:25 +0000
From:      bugzilla-noreply@freebsd.org
To:        freebsd-bugs@FreeBSD.org
Subject:   [Bug 202892] open with O_CREAT | O_DIRECTORY when path references a symlink
Message-ID:  <bug-202892-8@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D202892

            Bug ID: 202892
           Summary: open with O_CREAT | O_DIRECTORY when path references a
                    symlink
           Product: Base System
           Version: 11.0-CURRENT
          Hardware: amd64
                OS: Any
            Status: New
          Severity: Affects Many People
          Priority: ---
         Component: kern
          Assignee: freebsd-bugs@FreeBSD.org
          Reporter: freebsd@tom-ridge.com

The following test code (thanks R Watson) tries to call open with O_CREAT |
O_DIRECTORY, on a path that references a broken symlink. The symlink is
removed, a file is created, and the call to open returns with an error ENOT=
DIR.

There are similar strange behaviours. For example, O_CREAT | O_DIRECTORY |
O_EXCL on a symlink to a directory will result in the symlink being removed=
, a
file being created, and the call returning with an error. POSIX says "If O_=
EXCL
and O_CREAT are set, and path names a symbolic link, open() shall fail and =
set
errno to [EEXIST], regardless of the contents of the symbolic link. " (
http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html ) but I'm
not sure whether FreeBSD aims for compliance here. Even if FreeBSD doesn't =
aim
for compliance, this behaviour possibly breaks a possible POSIX invariant:
calls which return with errors do not alter the underlying file system state
(here, we get an error, but a symlink is removed and a new file is created).


#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int
main(int argc, char *argv[])
{
        int fd;

        /* Setup. */
        if (unlink("broken") <=3D 0 && errno !=3D ENOENT)
                err(-1, "unlink(broken)");
        if (unlink("target") <=3D 0 && errno !=3D ENOENT)
                err(-1, "unlink(target)");
        if (symlink("target", "broken") < 0)
                err(-1, "symlink(target, broken)");

        /* Test. */
        fd =3D open("broken", O_CREAT | O_DIRECTORY, 0600);
        if (fd >=3D 0)
                errx(-1, "open(broken, O_CREAT | O_DIRECTORY) - no error");
        else
                printf("Error on open() was %s\n", strerror(errno));
=EF=BF=BC

}

Thanks

--=20
You are receiving this mail because:
You are the assignee for the bug.=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-202892-8>