[glibc] 01/01: hurd-i386/tg-faccessat.diff: Finish faccessat implementation
This is an automated email from the git hooks/post-receive script.
sthibault pushed a commit to branch sid
in repository glibc.
commit 49d6825f2cee4b8d829f9e4780ecf3582d1d86c6
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Sat Jun 4 19:58:21 2016 +0000
hurd-i386/tg-faccessat.diff: Finish faccessat implementation
Fixes findutils.
---
debian/changelog | 2 +
debian/patches/hurd-i386/tg-faccessat.diff | 472 +++++++++++++++++++++++++++++
debian/patches/series | 1 +
3 files changed, 475 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index fa7eaf0..0a8f97d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -3,6 +3,8 @@ glibc (2.22-11) UNRELEASED; urgency=medium
[ Samuel Thibault ]
* hurd-i386/tg-poll_errors_fixes.diff: Fix crash when calling poll or select
on a fd which had never been allocated. Closes: #826175.
+ * hurd-i386/tg-faccessat.diff: Finish faccessat implementation. Fixes
+ findutils.
[ Aurelien Jarno ]
* Update from upstream stable branch.
diff --git a/debian/patches/hurd-i386/tg-faccessat.diff b/debian/patches/hurd-i386/tg-faccessat.diff
new file mode 100644
index 0000000..9a4a560
--- /dev/null
+++ b/debian/patches/hurd-i386/tg-faccessat.diff
@@ -0,0 +1,472 @@
+From: Samuel Thibault <samuel.thibault@ens-lyon.org>
+Subject: [PATCH] Implement faccessat without AT_EACCESS flag
+
+* hurd/hurd/fd.h: Include <fcntl.h>
+(__hurd_at_flags): New function.
+* hurd/lookup-at.c (__file_name_lookup_at): Replace flag computation
+with call to __hurd_at_flags.
+* include/unistd.h (__faccessat): Add declaration.
+* sysdeps/mach/hurd/access.c (__access): Move implementation to
+__faccessat, and replace it with a call to __faccessat.
+* sysdeps/mach/hurd/euidaccess.c (__euidaccess): Replace implementation
+with a call to __faccessat.
+* sysdeps/mach/hurd/faccessat.c (faccessat): Rename into...
+(__faccessat): ... this. Move implementation of __access into it when
+AT_FLAGS does not contain AT_EACCESS. Make it call __hurd_at_flags, add
+reauthenticate_cwdir_at helper to implement AT mechanism.
+(faccessat): Define weak alias.
+
+---
+ hurd/hurd/fd.h | 21 ++++++
+ hurd/lookup-at.c | 13 +---
+ include/unistd.h | 1 +
+ sysdeps/mach/hurd/access.c | 120 +-------------------------------
+ sysdeps/mach/hurd/euidaccess.c | 31 +--------
+ sysdeps/mach/hurd/faccessat.c | 152 +++++++++++++++++++++++++++++++++++++----
+ 6 files changed, 165 insertions(+), 173 deletions(-)
+
+diff --git a/hurd/hurd/fd.h b/hurd/hurd/fd.h
+index adb865a..1f22153 100644
+--- a/hurd/hurd/fd.h
++++ b/hurd/hurd/fd.h
+@@ -26,6 +26,7 @@
+ #include <hurd/hurd_types.h>
+ #include <hurd/port.h>
+ #include <sys/socket.h>
++#include <fcntl.h>
+
+
+ /* Structure representing a file descriptor. */
+@@ -254,6 +255,26 @@ extern int _hurd_select (int nfds, struct pollfd *pollfds,
+ const struct timespec *timeout,
+ const sigset_t *sigmask);
+
++/* Apply AT_FLAGS on FLAGS, in preparation for calling
++ __hurd_file_name_lookup. */
++
++_HURD_FD_H_EXTERN_INLINE error_t
++__hurd_at_flags (int *at_flags, int *flags)
++{
++ if ((*at_flags & AT_SYMLINK_FOLLOW) && (*at_flags & AT_SYMLINK_NOFOLLOW))
++ return EINVAL;
++
++ *flags |= (*at_flags & AT_SYMLINK_NOFOLLOW) ? O_NOLINK : 0;
++ *at_flags &= ~AT_SYMLINK_NOFOLLOW;
++ if (*at_flags & AT_SYMLINK_FOLLOW)
++ *flags &= ~O_NOLINK;
++ *at_flags &= ~AT_SYMLINK_FOLLOW;
++ if (*at_flags != 0)
++ return EINVAL;
++
++ return 0;
++}
++
+ /* Variant of file_name_lookup used in *at function implementations.
+ AT_FLAGS may only contain AT_SYMLINK_FOLLOW or AT_SYMLINK_NOFOLLOW,
+ which will remove and add O_NOLINK from FLAGS respectively.
+diff --git a/hurd/lookup-at.c b/hurd/lookup-at.c
+index 0288bcf..d729f67 100644
+--- a/hurd/lookup-at.c
++++ b/hurd/lookup-at.c
+@@ -29,16 +29,9 @@ __file_name_lookup_at (int fd, int at_flags,
+ error_t err;
+ file_t result;
+
+- if ((at_flags & AT_SYMLINK_FOLLOW) && (at_flags & AT_SYMLINK_NOFOLLOW))
+- return (__hurd_fail (EINVAL), MACH_PORT_NULL);
+-
+- flags |= (at_flags & AT_SYMLINK_NOFOLLOW) ? O_NOLINK : 0;
+- at_flags &= ~AT_SYMLINK_NOFOLLOW;
+- if (at_flags & AT_SYMLINK_FOLLOW)
+- flags &= ~O_NOLINK;
+- at_flags &= ~AT_SYMLINK_FOLLOW;
+- if (at_flags != 0)
+- return (__hurd_fail (EINVAL), MACH_PORT_NULL);
++ err = __hurd_at_flags (&at_flags, &flags);
++ if (err)
++ return (__hurd_fail (err), MACH_PORT_NULL);
+
+ if (fd == AT_FDCWD || file_name[0] == '/')
+ return __file_name_lookup (file_name, flags, mode);
+diff --git a/include/unistd.h b/include/unistd.h
+index a5cbc5d..09f9342 100644
+--- a/include/unistd.h
++++ b/include/unistd.h
+@@ -23,6 +23,7 @@ libc_hidden_proto (readlinkat)
+ /* Now define the internal interfaces. */
+ extern int __access (const char *__name, int __type);
+ extern int __euidaccess (const char *__name, int __type);
++extern int __faccessat (int __fd, const char *__file, int __type, int __flag);
+ extern __off64_t __lseek64 (int __fd, __off64_t __offset, int __whence);
+ extern __off_t __lseek (int __fd, __off_t __offset, int __whence);
+ libc_hidden_proto (__lseek)
+diff --git a/sysdeps/mach/hurd/access.c b/sysdeps/mach/hurd/access.c
+index 3a54df7..9379689 100644
+--- a/sysdeps/mach/hurd/access.c
++++ b/sysdeps/mach/hurd/access.c
+@@ -16,10 +16,6 @@
+ <http://www.gnu.org/licenses/>. */
+
+ #include <unistd.h>
+-#include <hurd.h>
+-#include <hurd/port.h>
+-#include <hurd/id.h>
+-#include <hurd/lookup.h>
+ #include <fcntl.h>
+
+ /* Test for access to FILE by our real user and group IDs. */
+@@ -28,121 +24,7 @@ __access (file, type)
+ const char *file;
+ int type;
+ {
+- error_t err;
+- file_t rcrdir, rcwdir, io;
+- int flags, allowed;
+-
+- error_t reauthenticate (int which, file_t *result)
+- {
+- /* Get a port to our root directory, authenticated with the real IDs. */
+- error_t err;
+- mach_port_t ref;
+- ref = __mach_reply_port ();
+- err = HURD_PORT_USE
+- (&_hurd_ports[which],
+- ({
+- err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
+- if (!err)
+- err = __auth_user_authenticate (_hurd_id.rid_auth,
+- ref, MACH_MSG_TYPE_MAKE_SEND,
+- result);
+- err;
+- }));
+- __mach_port_destroy (__mach_task_self (), ref);
+- return err;
+- }
+-
+- error_t init_port (int which, error_t (*operate) (mach_port_t))
+- {
+- switch (which)
+- {
+- case INIT_PORT_AUTH:
+- return (*operate) (_hurd_id.rid_auth);
+- case INIT_PORT_CRDIR:
+- return (reauthenticate (INIT_PORT_CRDIR, &rcrdir) ?:
+- (*operate) (rcrdir));
+- case INIT_PORT_CWDIR:
+- return (reauthenticate (INIT_PORT_CWDIR, &rcwdir) ?:
+- (*operate) (rcwdir));
+- default:
+- return _hurd_ports_use (which, operate);
+- }
+- }
+-
+- rcrdir = rcwdir = MACH_PORT_NULL;
+-
+- HURD_CRITICAL_BEGIN;
+-
+- __mutex_lock (&_hurd_id.lock);
+- /* Get _hurd_id up to date. */
+- if (err = _hurd_check_ids ())
+- goto lose;
+-
+- if (_hurd_id.rid_auth == MACH_PORT_NULL)
+- {
+- /* Set up _hurd_id.rid_auth. This is a special auth server port
+- which uses the real uid and gid (the first aux uid and gid) as
+- the only effective uid and gid. */
+-
+- if (_hurd_id.aux.nuids < 1 || _hurd_id.aux.ngids < 1)
+- {
+- /* We do not have a real UID and GID. Lose, lose, lose! */
+- err = EGRATUITOUS;
+- goto lose;
+- }
+-
+- /* Create a new auth port using our real UID and GID (the first
+- auxiliary UID and GID) as the only effective IDs. */
+- if (err = __USEPORT (AUTH,
+- __auth_makeauth (port,
+- NULL, MACH_MSG_TYPE_COPY_SEND, 0,
+- _hurd_id.aux.uids, 1,
+- _hurd_id.aux.uids,
+- _hurd_id.aux.nuids,
+- _hurd_id.aux.gids, 1,
+- _hurd_id.aux.gids,
+- _hurd_id.aux.ngids,
+- &_hurd_id.rid_auth)))
+- goto lose;
+- }
+-
+- if (!err)
+- /* Look up the file name using the modified init ports. */
+- err = __hurd_file_name_lookup (&init_port, &__getdport, 0,
+- file, 0, 0, &io);
+-
+- /* We are done with _hurd_id.rid_auth now. */
+- lose:
+- __mutex_unlock (&_hurd_id.lock);
+-
+- HURD_CRITICAL_END;
+-
+- if (rcrdir != MACH_PORT_NULL)
+- __mach_port_deallocate (__mach_task_self (), rcrdir);
+- if (rcwdir != MACH_PORT_NULL)
+- __mach_port_deallocate (__mach_task_self (), rcwdir);
+- if (err)
+- return __hurd_fail (err);
+-
+- /* Find out what types of access we are allowed to this file. */
+- err = __file_check_access (io, &allowed);
+- __mach_port_deallocate (__mach_task_self (), io);
+- if (err)
+- return __hurd_fail (err);
+-
+- flags = 0;
+- if (type & R_OK)
+- flags |= O_READ;
+- if (type & W_OK)
+- flags |= O_WRITE;
+- if (type & X_OK)
+- flags |= O_EXEC;
+-
+- if (flags & ~allowed)
+- /* We are not allowed all the requested types of access. */
+- return __hurd_fail (EACCES);
+-
+- return 0;
++ return __faccessat (AT_FDCWD, file, type, 0);
+ }
+
+ weak_alias (__access, access)
+diff --git a/sysdeps/mach/hurd/euidaccess.c b/sysdeps/mach/hurd/euidaccess.c
+index 5b96a3c..a4da9da 100644
+--- a/sysdeps/mach/hurd/euidaccess.c
++++ b/sysdeps/mach/hurd/euidaccess.c
+@@ -16,44 +16,15 @@
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+-#include <errno.h>
+-#include <stddef.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+-#include <hurd.h>
+
+ int
+ __euidaccess (file, type)
+ const char *file;
+ int type;
+ {
+- error_t err;
+- file_t port;
+- int allowed, flags;
+-
+- port = __file_name_lookup (file, 0, 0);
+- if (port == MACH_PORT_NULL)
+- return -1;
+-
+- /* Find out what types of access we are allowed to this file. */
+- err = __file_check_access (port, &allowed);
+- __mach_port_deallocate (__mach_task_self (), port);
+- if (err)
+- return __hurd_fail (err);
+-
+- flags = 0;
+- if (type & R_OK)
+- flags |= O_READ;
+- if (type & W_OK)
+- flags |= O_WRITE;
+- if (type & X_OK)
+- flags |= O_EXEC;
+-
+- if (flags & ~allowed)
+- /* We are not allowed all the requested types of access. */
+- return __hurd_fail (EACCES);
+-
+- return 0;
++ return __faccessat (AT_FDCWD, file, type, AT_EACCESS);
+ }
+ weak_alias (__euidaccess, euidaccess)
+ weak_alias (__euidaccess, eaccess)
+diff --git a/sysdeps/mach/hurd/faccessat.c b/sysdeps/mach/hurd/faccessat.c
+index 91bec43..5ca7ff7 100644
+--- a/sysdeps/mach/hurd/faccessat.c
++++ b/sysdeps/mach/hurd/faccessat.c
+@@ -23,33 +23,156 @@
+ #include <sys/types.h>
+ #include <hurd.h>
+ #include <hurd/fd.h>
++#include <hurd/port.h>
++#include <hurd/id.h>
++#include <hurd/lookup.h>
+
+ int
+-faccessat (fd, file, type, flag)
++__faccessat (fd, file, type, at_flags)
+ int fd;
+ const char *file;
+ int type;
+- int flag;
++ int at_flags;
+ {
+ error_t err;
+- file_t port;
+- int allowed, flags;
++ file_t rcrdir, rcwdir, io;
++ int flags, allowed;
+
+- if ((flag & AT_EACCESS) == 0)
++ if ((at_flags & AT_EACCESS) == AT_EACCESS)
+ {
+- if (fd == AT_FDCWD || file[0] == '/')
+- return __access (file, type);
+- __set_errno (ENOTSUP); /* XXX later */
+- return -1;
++ /* Use effective permissions. */
++ io = __file_name_lookup_at (fd, at_flags &~ AT_EACCESS, file, 0, 0);
++ if (io == MACH_PORT_NULL)
++ return -1;
+ }
++ else
++ {
++ /* We have to use real permissions instead of the
++ usual effective permissions. */
++
++ int hurd_flags = 0;
++ __hurd_at_flags (&at_flags, &hurd_flags);
++
++ error_t reauthenticate_cwdir_at (file_t *result)
++ {
++ /* Get a port to the FD directory, authenticated with the real IDs. */
++ error_t err;
++ mach_port_t ref;
++ ref = __mach_reply_port ();
++ err = HURD_DPORT_USE
++ (fd,
++ ({
++ err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
++ if (!err)
++ err = __auth_user_authenticate (_hurd_id.rid_auth,
++ ref, MACH_MSG_TYPE_MAKE_SEND,
++ result);
++ err;
++ }));
++ __mach_port_destroy (__mach_task_self (), ref);
++ return err;
++ }
++
++ error_t reauthenticate (int which, file_t *result)
++ {
++ /* Get a port to our root directory, authenticated with the real IDs. */
++ error_t err;
++ mach_port_t ref;
++ ref = __mach_reply_port ();
++ err = HURD_PORT_USE
++ (&_hurd_ports[which],
++ ({
++ err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
++ if (!err)
++ err = __auth_user_authenticate (_hurd_id.rid_auth,
++ ref, MACH_MSG_TYPE_MAKE_SEND,
++ result);
++ err;
++ }));
++ __mach_port_destroy (__mach_task_self (), ref);
++ return err;
++ }
++
++ error_t init_port (int which, error_t (*operate) (mach_port_t))
++ {
++ switch (which)
++ {
++ case INIT_PORT_AUTH:
++ return (*operate) (_hurd_id.rid_auth);
++ case INIT_PORT_CRDIR:
++ return (reauthenticate (INIT_PORT_CRDIR, &rcrdir) ?:
++ (*operate) (rcrdir));
++ case INIT_PORT_CWDIR:
++ if (fd == AT_FDCWD || file[0] == '/')
++ return (reauthenticate (INIT_PORT_CWDIR, &rcwdir) ?:
++ (*operate) (rcwdir));
++ else
++ return (reauthenticate_cwdir_at (&rcwdir) ?:
++ (*operate) (rcwdir));
++ default:
++ return _hurd_ports_use (which, operate);
++ }
++ }
++
++ rcrdir = rcwdir = MACH_PORT_NULL;
++
++ HURD_CRITICAL_BEGIN;
++
++ __mutex_lock (&_hurd_id.lock);
++ /* Get _hurd_id up to date. */
++ if (err = _hurd_check_ids ())
++ goto lose;
+
+- port = __file_name_lookup_at (fd, flag &~ AT_EACCESS, file, 0, 0);
+- if (port == MACH_PORT_NULL)
+- return -1;
++ if (_hurd_id.rid_auth == MACH_PORT_NULL)
++ {
++ /* Set up _hurd_id.rid_auth. This is a special auth server port
++ which uses the real uid and gid (the first aux uid and gid) as
++ the only effective uid and gid. */
++
++ if (_hurd_id.aux.nuids < 1 || _hurd_id.aux.ngids < 1)
++ {
++ /* We do not have a real UID and GID. Lose, lose, lose! */
++ err = EGRATUITOUS;
++ goto lose;
++ }
++
++ /* Create a new auth port using our real UID and GID (the first
++ auxiliary UID and GID) as the only effective IDs. */
++ if (err = __USEPORT (AUTH,
++ __auth_makeauth (port,
++ NULL, MACH_MSG_TYPE_COPY_SEND, 0,
++ _hurd_id.aux.uids, 1,
++ _hurd_id.aux.uids,
++ _hurd_id.aux.nuids,
++ _hurd_id.aux.gids, 1,
++ _hurd_id.aux.gids,
++ _hurd_id.aux.ngids,
++ &_hurd_id.rid_auth)))
++ goto lose;
++ }
++
++ if (!err)
++ /* Look up the file name using the modified init ports. */
++ err = __hurd_file_name_lookup (&init_port, &__getdport, 0,
++ file, hurd_flags, 0, &io);
++
++ /* We are done with _hurd_id.rid_auth now. */
++ lose:
++ __mutex_unlock (&_hurd_id.lock);
++
++ HURD_CRITICAL_END;
++
++ if (rcrdir != MACH_PORT_NULL)
++ __mach_port_deallocate (__mach_task_self (), rcrdir);
++ if (rcwdir != MACH_PORT_NULL)
++ __mach_port_deallocate (__mach_task_self (), rcwdir);
++ if (err)
++ return __hurd_fail (err);
++ }
+
+ /* Find out what types of access we are allowed to this file. */
+- err = __file_check_access (port, &allowed);
+- __mach_port_deallocate (__mach_task_self (), port);
++ err = __file_check_access (io, &allowed);
++ __mach_port_deallocate (__mach_task_self (), io);
+ if (err)
+ return __hurd_fail (err);
+
+@@ -67,3 +190,4 @@ faccessat (fd, file, type, flag)
+
+ return 0;
+ }
++weak_alias (__faccessat, faccessat)
+--
+tg: (58695b8..) t/faccessat (depends on: baseline)
diff --git a/debian/patches/series b/debian/patches/series
index 6d657f6..a227a88 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -159,6 +159,7 @@ hurd-i386/cvs-gprof-tick.diff
hurd-i386/cvs-IPV6_PKTINFO.diff
hurd-i386/cvs-i686-link.diff
hurd-i386/cvs-check-local-headers.diff
+hurd-i386/tg-faccessat.diff
i386/local-biarch.diff
i386/local-cmov.diff
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-glibc/glibc.git
Reply to: