[Bug 202892] open with O_CREAT | O_DIRECTORY when path references a symlink
bugzilla-noreply at freebsd.org
bugzilla-noreply at freebsd.org
Fri Sep 4 14:09:25 UTC 2015
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=202892
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 at FreeBSD.org
Reporter: freebsd at 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 ENOTDIR.
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") <= 0 && errno != ENOENT)
err(-1, "unlink(broken)");
if (unlink("target") <= 0 && errno != ENOENT)
err(-1, "unlink(target)");
if (symlink("target", "broken") < 0)
err(-1, "symlink(target, broken)");
/* Test. */
fd = open("broken", O_CREAT | O_DIRECTORY, 0600);
if (fd >= 0)
errx(-1, "open(broken, O_CREAT | O_DIRECTORY) - no error");
else
printf("Error on open() was %s\n", strerror(errno));

}
Thanks
--
You are receiving this mail because:
You are the assignee for the bug.
More information about the freebsd-bugs
mailing list