summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.topdeps2
-rw-r--r--.topmsg20
-rw-r--r--hurd/lookup-retry.c36
3 files changed, 28 insertions, 30 deletions
diff --git a/.topdeps b/.topdeps
index df7c3c6e56..180b47c18b 100644
--- a/.topdeps
+++ b/.topdeps
@@ -1 +1 @@
-9a869d822025be8e43b78234997b10bf0cf9d859
+baseline
diff --git a/.topmsg b/.topmsg
index dd6634c886..663abf4b87 100644
--- a/.topmsg
+++ b/.topmsg
@@ -1,16 +1,10 @@
-Subject: Baseline for our topic branches.
+From: Samuel Thibault <samuel.thibault@ens-lyon.org>
+Subject: [PATCH] hurd: Fix O_NOFOLLOW
----
+The error code documented by POSIX for opening a symlink with O_NOFOLLOW
+is ELOOP.
-This need not strictly be a TopGit branch, but it is for easy synchronization
-between different machines.
+Also, if the translator does not expose symlink as a symlink translator but
+as a S_IFLNK file, O_NOFOLLOW needs to return ELOOP too.
-As the baseline is merged into the topic branches, it is forward-only.
-
-To advance it:
-
- $ echo [SHA1] > .topdeps
- $ git commit -m Advance. -- .topdeps
- $ tg update
-
----
+Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
diff --git a/hurd/lookup-retry.c b/hurd/lookup-retry.c
index aee2ba8f93..b7a6a2b2a5 100644
--- a/hurd/lookup-retry.c
+++ b/hurd/lookup-retry.c
@@ -127,7 +127,7 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
{
/* In Linux, O_NOFOLLOW means to reject symlinks. If we
did an O_NOLINK lookup above and io_stat here to check
- for S_IFLNK, a translator like firmlink could easily
+ for S_IFLNK only, a translator like firmlink could easily
spoof this check by not showing S_IFLNK, but in fact
redirecting the lookup to some other name
(i.e. opening the very same holes a symlink would).
@@ -145,23 +145,27 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port)
one exception to our general translator-based rule. */
struct stat64 st;
err = __io_stat (*result, &st);
- if (!err
- && (st.st_mode & (S_IPTRANS|S_IATRANS)))
+ if (!err)
{
- if (st.st_uid != 0)
- err = ENOENT;
- else if (st.st_mode & S_IPTRANS)
+ if (S_ISLNK(st.st_mode))
+ err = ELOOP;
+ else if (st.st_mode & (S_IPTRANS|S_IATRANS))
{
- char buf[1024];
- char *trans = buf;
- size_t translen = sizeof buf;
- err = __file_get_translator (*result,
- &trans, &translen);
- if (!err
- && translen > sizeof _HURD_SYMLINK
- && !memcmp (trans,
- _HURD_SYMLINK, sizeof _HURD_SYMLINK))
- err = ENOENT;
+ if (st.st_uid != 0)
+ err = ELOOP;
+ else if (st.st_mode & S_IPTRANS)
+ {
+ char buf[1024];
+ char *trans = buf;
+ size_t translen = sizeof buf;
+ err = __file_get_translator (*result,
+ &trans, &translen);
+ if (!err
+ && translen > sizeof _HURD_SYMLINK
+ && !memcmp (trans,
+ _HURD_SYMLINK, sizeof _HURD_SYMLINK))
+ err = ELOOP;
+ }
}
}
}