The following (untested) patch reverts the defective O_SEARCH implementation that was committed along with the *at calls back in November.
I am currently building and testing it and will commit it when that finishes. I have left O_SEARCH defined and visible and made open() explicitly ignore it. This way, most code that tries to use it will continue to build and run. I've also arranged lib/libc/c063/t_o_search.c so that the tests that make use of the O_SEARCH semantics will disappear until O_SEARCH comes back, and fixed some mistakes and/or incorrect hacks that were causing some of these to succeed despite the broken O_SEARCH implementation. The man page changes at the end are essentially all the same. ------ diff -r 660c8bed4e78 sys/kern/vfs_syscalls.c --- a/sys/kern/vfs_syscalls.c Sat Jan 12 15:03:39 2013 -0500 +++ b/sys/kern/vfs_syscalls.c Sat Jan 12 18:24:09 2013 -0500 @@ -181,14 +181,6 @@ if ((error = fd_getvnode(fdat, &dfp)) != 0) goto out; - if (!(dfp->f_flag & FSEARCH)) { - vn_lock(dfp->f_data, LK_EXCLUSIVE); - error = VOP_ACCESS(dfp->f_data, VEXEC, l->l_cred); - VOP_UNLOCK(dfp->f_data); - if (error) - goto cleanup; - } - NDAT(ndp, dfp->f_data); } @@ -213,14 +205,6 @@ if ((error = fd_getvnode(fdat, &dfp)) != 0) goto out; - if (!(dfp->f_flag & FSEARCH)) { - vn_lock(dfp->f_data, LK_EXCLUSIVE); - error = VOP_ACCESS(dfp->f_data, VEXEC, l->l_cred); - VOP_UNLOCK(dfp->f_data); - if (error) - goto cleanup; - } - dvp = dfp->f_data; } else { dvp = NULL; @@ -1577,6 +1561,10 @@ int indx, error; struct nameidata nd; + if (open_flags & O_SEARCH) { + open_flags &= ~(int)O_SEARCH; + } + flags = FFLAGS(open_flags); if ((flags & (FREAD | FWRITE)) == 0) return EINVAL; @@ -1641,7 +1629,6 @@ /* * Check permissions, allocate an open file structure, * and call the device open routine if any. - * XXX implement O_SEARCH */ static int do_sys_openat(lwp_t *l, int fdat, const char *path, int flags, @@ -1662,19 +1649,10 @@ goto out; dvp = dfp->f_data; - - if (!(dfp->f_flag & FSEARCH)) { - vn_lock(dfp->f_data, LK_EXCLUSIVE); - error = VOP_ACCESS(dfp->f_data, VEXEC, l->l_cred); - VOP_UNLOCK(dfp->f_data); - if (error) - goto cleanup; - } } error = do_open(l, dvp, pb, flags, mode, fd); -cleanup: if (dfp != NULL) fd_putfile(fdat); out: @@ -1988,6 +1966,10 @@ 0, NULL, NULL, NULL))) return (error); + if (oflags & O_SEARCH) { + oflags &= ~(int)O_SEARCH; + } + flags = FFLAGS(oflags); if ((flags & (FREAD | FWRITE)) == 0) return (EINVAL); diff -r 660c8bed4e78 sys/sys/fcntl.h --- a/sys/sys/fcntl.h Sat Jan 12 15:03:39 2013 -0500 +++ b/sys/sys/fcntl.h Sat Jan 12 18:24:09 2013 -0500 @@ -131,7 +131,7 @@ #define O_MASK (O_ACCMODE|O_NONBLOCK|O_APPEND|O_SHLOCK|O_EXLOCK|\ O_ASYNC|O_SYNC|O_CREAT|O_TRUNC|O_EXCL|O_DSYNC|\ O_RSYNC|O_NOCTTY|O_ALT_IO|O_NOFOLLOW|O_DIRECT|\ - O_DIRECTORY|O_CLOEXEC|O_NOSIGPIPE|O_SEARCH) + O_DIRECTORY|O_CLOEXEC|O_NOSIGPIPE) #define FMARK 0x00001000 /* mark during gc() */ #define FDEFER 0x00002000 /* defer for next gc pass */ @@ -141,7 +141,7 @@ #define FKIOCTL 0x80000000 /* kernel originated ioctl */ /* bits settable by fcntl(F_SETFL, ...) */ #define FCNTLFLAGS (FAPPEND|FASYNC|FFSYNC|FNONBLOCK|FDSYNC|FRSYNC|FALTIO|\ - FDIRECT|FNOSIGPIPE|FSEARCH) + FDIRECT|FNOSIGPIPE) /* bits to save after open(2) */ #define FMASK (FREAD|FWRITE|FCNTLFLAGS) #endif /* _KERNEL */ @@ -166,7 +166,6 @@ #define FRSYNC O_RSYNC /* kernel */ #define FALTIO O_ALT_IO /* kernel */ #define FDIRECT O_DIRECT /* kernel */ -#define FSEARCH O_SEARCH /* kernel */ #endif /* diff -r 660c8bed4e78 tests/lib/libc/c063/t_o_search.c --- a/tests/lib/libc/c063/t_o_search.c Sat Jan 12 15:03:39 2013 -0500 +++ b/tests/lib/libc/c063/t_o_search.c Sat Jan 12 18:24:09 2013 -0500 @@ -42,14 +42,24 @@ #include <pwd.h> #include <sys/param.h> +/* + * dholland 20130112: disable tests that require O_SEARCH semantics + * until a decision is reached about the semantics of O_SEARCH and a + * non-broken implementation is available. + */ +#if (O_MASK & O_SEARCH) != 0 +#define USE_O_SEARCH +#endif + #define DIR "dir" #define FILE "dir/o_search" #define BASEFILE "o_search" + ATF_TC_WITH_CLEANUP(o_search_perm1); ATF_TC_HEAD(o_search_perm1, tc) { - atf_tc_set_md_var(tc, "descr", "See that openat enforce search permission"); + atf_tc_set_md_var(tc, "descr", "See that openat enforces search permission"); atf_tc_set_md_var(tc, "require.user", "unprivileged"); } @@ -81,10 +91,13 @@ (void)rmdir(DIR); } + +#ifdef USE_O_SEARCH + ATF_TC_WITH_CLEANUP(o_search_root_flag1); ATF_TC_HEAD(o_search_root_flag1, tc) { - atf_tc_set_md_var(tc, "descr", "See that openat honours O_SEARCH"); + atf_tc_set_md_var(tc, "descr", "See that root openat honours O_SEARCH"); atf_tc_set_md_var(tc, "require.user", "root"); } @@ -120,6 +133,7 @@ (void)rmdir(DIR); } + ATF_TC_WITH_CLEANUP(o_search_unpriv_flag1); ATF_TC_HEAD(o_search_unpriv_flag1, tc) { @@ -141,14 +155,14 @@ ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); ATF_REQUIRE(close(fd) == 0); - ATF_REQUIRE(fchmod(dfd, 744) == 0); + ATF_REQUIRE(fchmod(dfd, 644) == 0); ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); ATF_REQUIRE(close(fd) == 0); ATF_REQUIRE(fchmod(dfd, 444) == 0); - ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) == -1); + ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1); ATF_REQUIRE(close(dfd) == 0); } @@ -159,10 +173,13 @@ (void)rmdir(DIR); } +#endif /* USE_O_SEARCH */ + + ATF_TC_WITH_CLEANUP(o_search_perm2); ATF_TC_HEAD(o_search_perm2, tc) { - atf_tc_set_md_var(tc, "descr", "See that fstatat enforce search permission"); + atf_tc_set_md_var(tc, "descr", "See that faccessat enforces search permission"); atf_tc_set_md_var(tc, "require.user", "unprivileged"); } @@ -192,10 +209,13 @@ (void)rmdir(DIR); } + +#ifdef USE_O_SEARCH + ATF_TC_WITH_CLEANUP(o_search_root_flag2); ATF_TC_HEAD(o_search_root_flag2, tc) { - atf_tc_set_md_var(tc, "descr", "See that fstatat honours O_SEARCH"); + atf_tc_set_md_var(tc, "descr", "See that root fstatat honours O_SEARCH"); atf_tc_set_md_var(tc, "require.user", "root"); } @@ -229,6 +249,7 @@ (void)rmdir(DIR); } + ATF_TC_WITH_CLEANUP(o_search_unpriv_flag2); ATF_TC_HEAD(o_search_unpriv_flag2, tc) { @@ -249,7 +270,7 @@ ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); - ATF_REQUIRE(fchmod(dfd, 744) == 0); + ATF_REQUIRE(fchmod(dfd, 644) == 0); ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0); @@ -264,7 +285,10 @@ { (void)unlink(FILE); (void)rmdir(DIR); -} +} + +#endif /* USE_O_SEARCH */ + ATF_TC_WITH_CLEANUP(o_search_notdir); ATF_TC_HEAD(o_search_notdir, tc) @@ -295,11 +319,15 @@ { ATF_TP_ADD_TC(tp, o_search_perm1); +#ifdef USE_O_SEARCH ATF_TP_ADD_TC(tp, o_search_root_flag1); ATF_TP_ADD_TC(tp, o_search_unpriv_flag1); +#endif ATF_TP_ADD_TC(tp, o_search_perm2); +#ifdef USE_O_SEARCH ATF_TP_ADD_TC(tp, o_search_root_flag2); ATF_TP_ADD_TC(tp, o_search_unpriv_flag2); +#endif ATF_TP_ADD_TC(tp, o_search_notdir); return atf_no_error(); diff -r 660c8bed4e78 lib/libc/sys/access.2 --- a/lib/libc/sys/access.2 Sat Jan 12 15:03:39 2013 -0500 +++ b/lib/libc/sys/access.2 Sat Jan 12 18:24:09 2013 -0500 @@ -107,11 +107,26 @@ The file descriptor .Fa fd must name a directory. -Search permission is required on this directory except if -.Fa fd -was opened with the -.Dv O_SEARCH -flag. +Search permission is required on this directory. +.\" (These alternatives await a decision about the semantics of O_SEARCH) +.\" Search permission is required on this directory, except if +.\" .Fa fd +.\" was opened with the +.\" .Dv O_SEARCH +.\" flag. +.\" - or - +.\" The directory referred to by +.\" .Fa fd +.\" must have been opened with the +.\" .Dv O_SEARCH +.\" flag. +.\" - or - +.\" The directory referred to by +.\" .Fa fd +.\" must have been opened with the +.\" .Dv O_SEARCH +.\" flag or must be searchable by the current process at the time the +.\" call is made. .Pp The .Fa flags diff -r 660c8bed4e78 lib/libc/sys/chmod.2 --- a/lib/libc/sys/chmod.2 Sat Jan 12 15:03:39 2013 -0500 +++ b/lib/libc/sys/chmod.2 Sat Jan 12 18:24:09 2013 -0500 @@ -90,7 +90,18 @@ In that case, it is looked up from a directory whose file descriptor was passed as .Fa fd . -Search permission is required on +Search permission is required on this directory. +.\" (These alternatives await a decision about the semantics of O_SEARCH) +.\" Search permission is required on this directory +.\" except if +.\" .Fa fd +.\" was opened with the +.\" .Dv O_SEARCH +.\" flag. +.\" - or - +.\" This file descriptor must have been opened with the +.\" .Dv O_SEARCH +.\" flag. .Fa fd except if that file descriptor was opened with the .Dv O_SEARCH diff -r 660c8bed4e78 lib/libc/sys/chown.2 --- a/lib/libc/sys/chown.2 Sat Jan 12 15:03:39 2013 -0500 +++ b/lib/libc/sys/chown.2 Sat Jan 12 18:24:09 2013 -0500 @@ -119,11 +119,18 @@ In that case, it is looked up from a directory whose file descriptor was passed as .Fa fd . -Search permission is required on -.Fa fd -except if that file descriptor was opened with the -.Dv O_SEARCH -flag. +Search permission is required on this directory. +.\" (These alternatives await a decision about the semantics of O_SEARCH) +.\" Search permission is required on this directory +.\" except if +.\" .Fa fd +.\" was opened with the +.\" .Dv O_SEARCH +.\" flag. +.\" - or - +.\" This file descriptor must have been opened with the +.\" .Dv O_SEARCH +.\" flag. .Fa fd can be set to .Dv AT_FDCWD diff -r 660c8bed4e78 lib/libc/sys/link.2 --- a/lib/libc/sys/link.2 Sat Jan 12 15:03:39 2013 -0500 +++ b/lib/libc/sys/link.2 Sat Jan 12 18:24:09 2013 -0500 @@ -94,11 +94,26 @@ .Fa fd1 (resp. .Fa fd2 ) . -Search permission is required on -passed directory file descriptors -except if they were opened with the -.Dv O_SEARCH -flag. +Search permission is required on the directories named by +.Fa fd1 +and +.Fa fd2. +.\" (These alternatives await a decision about the semantics of O_SEARCH) +.\" Search permission is required on the directories named by +.\" .Fa fd1 +.\" and +.\" .Fa fd2 +.\" unless they were opened with the +.\" .Dv O_SEARCH +.\" flag. +.\" - or - +.\" The directories named by +.\" .Fa fd1 +.\" and +.\" .Fa fd2 +.\" must have been opened with the +.\" .Dv O_SEARCH +.\" flag. .Fa fd1 or .Fa fd2 diff -r 660c8bed4e78 lib/libc/sys/mkdir.2 --- a/lib/libc/sys/mkdir.2 Sat Jan 12 15:03:39 2013 -0500 +++ b/lib/libc/sys/mkdir.2 Sat Jan 12 18:24:09 2013 -0500 @@ -62,11 +62,18 @@ In that case, it is looked up from a directory whose file descriptor was passed as .Fa fd . -Search permission is required on -.Fa fd -except if that file descriptor was opened with the -.Dv O_SEARCH -flag. +Search permission is required this directory. +.\" (These alternatives await a decision about the semantics of O_SEARCH) +.\" Search permission is required on this directory +.\" except if +.\" .Fa fd +.\" was opened with the +.\" .Dv O_SEARCH +.\" flag. +.\" - or - +.\" This file descriptor must have been opened with the +.\" .Dv O_SEARCH +.\" flag. .Fa fd can be set to .Dv AT_FDCWD diff -r 660c8bed4e78 lib/libc/sys/mkfifo.2 --- a/lib/libc/sys/mkfifo.2 Sat Jan 12 15:03:39 2013 -0500 +++ b/lib/libc/sys/mkfifo.2 Sat Jan 12 18:24:09 2013 -0500 @@ -64,11 +64,18 @@ In that case, it is looked up from a directory whose file descriptor was passed as .Fa fd . -Search permission is required on -.Fa fd -except if that file descriptor was opened with the -.Dv O_SEARCH -flag. +Search permission is required on this directory. +.\" (These alternatives await a decision about the semantics of O_SEARCH) +.\" Search permission is required on this directory +.\" except if +.\" .Fa fd +.\" was opened with the +.\" .Dv O_SEARCH +.\" flag. +.\" - or - +.\" This file descriptor must have been opened with the +.\" .Dv O_SEARCH +.\" flag. .Fa fd can be set to .Dv AT_FDCWD diff -r 660c8bed4e78 lib/libc/sys/mknod.2 --- a/lib/libc/sys/mknod.2 Sat Jan 12 15:03:39 2013 -0500 +++ b/lib/libc/sys/mknod.2 Sat Jan 12 18:24:09 2013 -0500 @@ -67,11 +67,18 @@ In that case, it is looked up from a directory whose file descriptor was passed as .Fa fd . -Search permission is required on -.Fa fd -except if that file descriptor was opened with the -.Dv O_SEARCH -option. +Search permission is required on this directory. +.\" (These alternatives await a decision about the semantics of O_SEARCH) +.\" Search permission is required on this directory +.\" except if +.\" .Fa fd +.\" was opened with the +.\" .Dv O_SEARCH +.\" flag. +.\" - or - +.\" This file descriptor must have been opened with the +.\" .Dv O_SEARCH +.\" flag. .Fa fd can be set to .Dv AT_FDCWD diff -r 660c8bed4e78 lib/libc/sys/open.2 --- a/lib/libc/sys/open.2 Sat Jan 12 15:03:39 2013 -0500 +++ b/lib/libc/sys/open.2 Sat Jan 12 18:24:09 2013 -0500 @@ -62,11 +62,18 @@ In that case, it is looked up from a directory whose file descriptor was passed as .Fa fd . -Search permission is required on -.Fa fd -except if that file descriptor was opened with the -.Dv O_SEARCH -option. +Search permission is required on this directory. +.\" (These alternatives await a decision about the semantics of O_SEARCH) +.\" Search permission is required on this directory +.\" except if +.\" .Fa fd +.\" was opened with the +.\" .Dv O_SEARCH +.\" flag. +.\" - or - +.\" This file descriptor must have been opened with the +.\" .Dv O_SEARCH +.\" flag. .Fa fd can be set to .Dv AT_FDCWD @@ -187,23 +194,24 @@ signal to be sent to the process group when I/O is possible, e.g., upon availability of data to be read. -.It Dv O_SEARCH -If opening a directory, search permission checks will not be performed on -subsequent usage of the file descriptor for looking up relative paths by -.Xr faccessat 2 , -.Xr fchmodat 2 , -.Xr fchownat 2 , -.Xr fstatat 2 , -.Xr linkat 2 , -.Xr mkdirat 2 , -.Xr mkfifoat 2 , -.Xr mknodat 2 , -.Xr openat 2 , -.Xr readlinkat 2 , -.Xr symlinkat 2 , -.Xr unlinkat 2 , -and -.Xr utimensat 2 . +.\" (This block awaits a decision about the semantics of O_SEARCH) +.\" .It Dv O_SEARCH +.\" If opening a directory, search permission checks will not be performed on +.\" subsequent usage of the file descriptor for looking up relative paths by +.\" .Xr faccessat 2 , +.\" .Xr fchmodat 2 , +.\" .Xr fchownat 2 , +.\" .Xr fstatat 2 , +.\" .Xr linkat 2 , +.\" .Xr mkdirat 2 , +.\" .Xr mkfifoat 2 , +.\" .Xr mknodat 2 , +.\" .Xr openat 2 , +.\" .Xr readlinkat 2 , +.\" .Xr symlinkat 2 , +.\" .Xr unlinkat 2 , +.\" and +.\" .Xr utimensat 2 . .El .Pp Opening a file with @@ -437,9 +445,10 @@ .Dv O_RSYNC are extensions defined in .St -p1003.1b-93 . -.Dv O_SEARCH -is defined in -.St -p1003.1-2008 . +.\" (This block awaits a decision about the semantics of O_SEARCH) +.\" .Dv O_SEARCH +.\" is defined in +.\" .St -p1003.1-2008 . .Pp The .Dv O_SHLOCK diff -r 660c8bed4e78 lib/libc/sys/readlink.2 --- a/lib/libc/sys/readlink.2 Sat Jan 12 15:03:39 2013 -0500 +++ b/lib/libc/sys/readlink.2 Sat Jan 12 18:24:09 2013 -0500 @@ -68,11 +68,18 @@ In that case, it is looked up from a directory whose file descriptor was passed as .Fa fd . -Search permission is required on -.Fa fd -except if that file descriptor was opened with the -.Dv O_SEARCH -flag. +Search permission is required on this directory. +.\" (These alternatives await a decision about the semantics of O_SEARCH) +.\" Search permission is required on this directory +.\" except if +.\" .Fa fd +.\" was opened with the +.\" .Dv O_SEARCH +.\" flag. +.\" - or - +.\" This file descriptor must have been opened with the +.\" .Dv O_SEARCH +.\" flag. .Fa fd can be set to .Dv AT_FDCWD diff -r 660c8bed4e78 lib/libc/sys/rename.2 --- a/lib/libc/sys/rename.2 Sat Jan 12 15:03:39 2013 -0500 +++ b/lib/libc/sys/rename.2 Sat Jan 12 18:24:09 2013 -0500 @@ -93,11 +93,26 @@ .Fa fromfd (resp. .Fa tofd ). -Search permission is required on -passed directory file descriptors -except if they were opened with the -.Dv O_SEARCH -option. +Search permission is required on the directories named by +.Fa fromfd +and +.Fa tofd. +.\" (These alternatives await a decision about the semantics of O_SEARCH) +.\" Search permission is required on the directories named by +.\" .Fa fromfd +.\" and +.\" .Fa tofd +.\" unless they were opened with the +.\" .Dv O_SEARCH +.\" flag. +.\" - or - +.\" The directories named by +.\" .Fa fromfd +.\" and +.\" .Fa tofd +.\" must have been opened with the +.\" .Dv O_SEARCH +.\" flag. .Fa fromfd or .Fa tofd diff -r 660c8bed4e78 lib/libc/sys/stat.2 --- a/lib/libc/sys/stat.2 Sat Jan 12 15:03:39 2013 -0500 +++ b/lib/libc/sys/stat.2 Sat Jan 12 18:24:09 2013 -0500 @@ -91,11 +91,18 @@ In that case, it is looked up from a directory whose file descriptor was passed as .Fa fd . -Search permission is required on -.Fa fd -except if that file descriptor was opened with the -.Dv O_SEARCH -option. +Search permission is required on this directory. +.\" (These alternatives await a decision about the semantics of O_SEARCH) +.\" Search permission is required on this directory +.\" except if +.\" .Fa fd +.\" was opened with the +.\" .Dv O_SEARCH +.\" flag. +.\" - or - +.\" This file descriptor must have been opened with the +.\" .Dv O_SEARCH +.\" flag. .Fa fd can be set to .Dv AT_FDCWD diff -r 660c8bed4e78 lib/libc/sys/symlink.2 --- a/lib/libc/sys/symlink.2 Sat Jan 12 15:03:39 2013 -0500 +++ b/lib/libc/sys/symlink.2 Sat Jan 12 18:24:09 2013 -0500 @@ -67,11 +67,18 @@ In that case, it is looked up from a directory whose file descriptor was passed as .Fa fd . -Search permission is required on -.Fa fd -except if that file descriptor was opened with the -.Dv O_SEARCH -flag. +Search permission is required on this directory. +.\" (These alternatives await a decision about the semantics of O_SEARCH) +.\" Search permission is required on this directory +.\" except if +.\" .Fa fd +.\" was opened with the +.\" .Dv O_SEARCH +.\" flag. +.\" - or - +.\" This file descriptor must have been opened with the +.\" .Dv O_SEARCH +.\" flag. .Fa fd can be set to .Dv AT_FDCWD diff -r 660c8bed4e78 lib/libc/sys/unlink.2 --- a/lib/libc/sys/unlink.2 Sat Jan 12 15:03:39 2013 -0500 +++ b/lib/libc/sys/unlink.2 Sat Jan 12 18:24:09 2013 -0500 @@ -70,11 +70,18 @@ In that case, it is looked up from a directory whose file descriptor was passed as .Fa fd . -Search permission is required on -.Fa fd -except if that file descriptor was opened with the -.Dv O_SEARCH -option. +Search permission is required on this directory. +.\" (These alternatives await a decision about the semantics of O_SEARCH) +.\" Search permission is required on this directory +.\" except if +.\" .Fa fd +.\" was opened with the +.\" .Dv O_SEARCH +.\" flag. +.\" - or - +.\" This file descriptor must have been opened with the +.\" .Dv O_SEARCH +.\" flag. .Fa fd can be set to .Dv AT_FDCWD diff -r 660c8bed4e78 lib/libc/sys/utimes.2 --- a/lib/libc/sys/utimes.2 Sat Jan 12 15:03:39 2013 -0500 +++ b/lib/libc/sys/utimes.2 Sat Jan 12 18:24:09 2013 -0500 @@ -129,11 +129,18 @@ In that case, it is looked up from a directory whose file descriptor was passed as .Fa fd . -Search permission is required on -.Fa fd -except if that file descriptor was opened with the -.Dv O_SEARCH -option. +Search permission is required on this directory. +.\" (These alternatives await a decision about the semantics of O_SEARCH) +.\" Search permission is required on this directory +.\" except if +.\" .Fa fd +.\" was opened with the +.\" .Dv O_SEARCH +.\" flag. +.\" - or - +.\" This file descriptor must have been opened with the +.\" .Dv O_SEARCH +.\" flag. .Fa fd can be set to .Dv AT_FDCWD -- David A. Holland dholl...@netbsd.org