[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[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: