public inbox for cygwin-cvs@sourceware.org help / color / mirror / Atom feed
From: Corinna Vinschen <corinna@sourceware.org> To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin/cygwin-3_4-branch] Cygwin: fix errno values set by readlinkat Date: Tue, 18 Apr 2023 11:54:34 +0000 (GMT) [thread overview] Message-ID: <20230418115434.74072385840E@sourceware.org> (raw) https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=4b8222983f914a7950987802e73fc069dffc3058 commit 4b8222983f914a7950987802e73fc069dffc3058 Author: Corinna Vinschen <corinna@vinschen.de> AuthorDate: Tue Apr 18 13:52:50 2023 +0200 Commit: Corinna Vinschen <corinna@vinschen.de> CommitDate: Tue Apr 18 13:53:09 2023 +0200 Cygwin: fix errno values set by readlinkat readlinkat(fd, "", ...) is supposed to return ENOENT per POSIX, but Cygwin returns EBADF. At the same time, we have to maintain the special feature of glibc that readlinkat(fd, "", ...) operates on fd, if fd is pointing at a symlink opened with O_PATH|O_NOFOLLOW. And, while fixing that, readlinkat(fd, path, ...) *still* has to set errno to EBADF, if fd is an invalid descriptor *and* path is a relative path. This required to change the evaluation order in the helper function gen_full_path_at. Last but not least, in case of the aforementioned glibc-like special handling for symlink descriptors, we have to make sure that errors from gen_full_path_at are not spilled into that special handling. Fixes: 6cc05784e16a ("Cygwin: readlinkat: allow pathname to be empty") Reported-by: Bruno Haible <bruno@clisp.org> Signed-off-by: Corinna Vinschen <corinna@vinschen.de> Diff: --- winsup/cygwin/release/3.4.7 | 3 +++ winsup/cygwin/syscalls.cc | 42 ++++++++++++++++++++++-------------------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/winsup/cygwin/release/3.4.7 b/winsup/cygwin/release/3.4.7 index 8ecfbc30a24b..7bc7d4a1ccdb 100644 --- a/winsup/cygwin/release/3.4.7 +++ b/winsup/cygwin/release/3.4.7 @@ -18,3 +18,6 @@ Bug Fixes - Fix return value of ilogbl(NaN). Addresses: https://cygwin.com/pipermail/cygwin/2023-April/253511.html + +- Fix error handling in readlinkat. + Addresses: https://cygwin.com/pipermail/cygwin/2023-April/253510.html diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index fff8af009fd1..a4e4af626db1 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -4415,19 +4415,6 @@ gen_full_path_at (char *path_ret, int dirfd, const char *pathname, set_errno (EFAULT); return -1; } - if (pathname) - { - if (!*pathname) - { - set_errno (ENOENT); - return -1; - } - if (strlen (pathname) >= PATH_MAX) - { - set_errno (ENAMETOOLONG); - return -1; - } - } if (pathname && isabspath_strict (pathname)) stpcpy (path_ret, pathname); else @@ -4459,6 +4446,16 @@ gen_full_path_at (char *path_ret, int dirfd, const char *pathname, } if (pathname) { + if (!*pathname) + { + set_errno (ENOENT); + return -1; + } + if (strlen (pathname) >= PATH_MAX) + { + set_errno (ENAMETOOLONG); + return -1; + } if (p[-1] != '/') *p++ = '/'; stpcpy (p, pathname); @@ -4803,21 +4800,26 @@ readlinkat (int dirfd, const char *__restrict pathname, char *__restrict buf, __try { char *path = tp.c_get (); + int save_errno = errno; int res = gen_full_path_at (path, dirfd, pathname); if (res) { - if (errno != ENOENT) + if (errno != ENOENT && errno != ENOTDIR) __leave; /* pathname is an empty string. This is OK if dirfd refers to a symlink that was opened with O_PATH | O_NOFOLLOW. - In this case, readlinkat operates on the symlink. */ + In this case, readlinkat operates on the symlink. + Don't propagate errors from gen_full_path_at after this point. */ + errno = save_errno; cygheap_fdget cfd (dirfd); - if (cfd < 0) - __leave; - if (!(cfd->issymlink () + if (cfd < 0 + || (!(cfd->issymlink () && cfd->get_flags () & O_PATH - && cfd->get_flags () & O_NOFOLLOW)) - __leave; + && cfd->get_flags () & O_NOFOLLOW))) + { + set_errno (ENOENT); + __leave; + } strcpy (path, cfd->get_name ()); } return readlink (path, buf, bufsize);
reply other threads:[~2023-04-18 11:54 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20230418115434.74072385840E@sourceware.org \ --to=corinna@sourceware.org \ --cc=cygwin-cvs@sourceware.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).