diff options
author | 2018-03-18 19:43:04 +0100 | |
---|---|---|
committer | 2018-03-18 19:43:04 +0100 | |
commit | 72103e73c9a76784b9e8b27a7d5b802178d6755b (patch) | |
tree | 1a250b52aba642cab342d056a09c08f1032f409c /hurd | |
parent | hurd: Fix O_NOFOLLOW (diff) | |
download | glibc-72103e73c9a76784b9e8b27a7d5b802178d6755b.tar.gz glibc-72103e73c9a76784b9e8b27a7d5b802178d6755b.tar.bz2 glibc-72103e73c9a76784b9e8b27a7d5b802178d6755b.zip |
hurd: Fix O_DIRECTORY | O_NOFOLLOW
Appending / to the path to be looked up would make us always follow a final
symlink, even with O_NOTRANS (since the final resolution is after the
'/'). In the O_DIRECTORY | O_NOFOLLOW case, we thus have to really open
the node and stat it, which we already do anyway, and check for
directory type.
* hurd/hurdlookup.c (__hurd_file_name_lookup): Do not append '/' to
path when flags contains O_NOFOLLOW.
* hurd/lookup-retry.c (__hurd_file_name_lookup_retry): Return ENOTDIR
if flags contains O_DIRECTORY and the result is a directory.
Diffstat (limited to 'hurd')
-rw-r--r-- | hurd/hurdlookup.c | 2 | ||||
-rw-r--r-- | hurd/lookup-retry.c | 2 |
2 files changed, 3 insertions, 1 deletions
diff --git a/hurd/hurdlookup.c b/hurd/hurdlookup.c index 1861d5879d..a642c49002 100644 --- a/hurd/hurdlookup.c +++ b/hurd/hurdlookup.c @@ -72,7 +72,7 @@ __hurd_file_name_lookup (error_t (*use_init_port) if (flags & O_NOFOLLOW) /* See lookup-retry.c about O_NOFOLLOW. */ flags |= O_NOTRANS; - if (flags & O_DIRECTORY) + if (flags & O_DIRECTORY && (flags & O_NOFOLLOW) == 0) { /* The caller wants to require that the file we look up is a directory. We can do this without an extra RPC by appending a trailing slash diff --git a/hurd/lookup-retry.c b/hurd/lookup-retry.c index 12b5c30962..b596848624 100644 --- a/hurd/lookup-retry.c +++ b/hurd/lookup-retry.c @@ -147,6 +147,8 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port) err = __io_stat (*result, &st); if (!err) { + if (flags & O_DIRECTORY && !S_ISDIR (st.st_mode)) + err = ENOTDIR; if (S_ISLNK (st.st_mode)) err = ELOOP; else if (st.st_mode & (S_IPTRANS|S_IATRANS)) |