This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch, master, updated. glibc-2.11-52-gaa98902


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  aa9890239a2aef81e64f3f22a31c7e01b6501f69 (commit)
       via  0f622686af3ae5a8f03dae886b08c260b38bda16 (commit)
       via  139ee080b6b428240bf49f3e6361f3ac729f891a (commit)
       via  fa214705b957d20621cb1190b467aa88bc9b69a3 (commit)
       via  21f2c22320c00c1627dd734794af7353ad7637b2 (commit)
      from  80b3a4ea1c4eb5641aa4c0cac57fe9df65ddba86 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=aa9890239a2aef81e64f3f22a31c7e01b6501f69

commit aa9890239a2aef81e64f3f22a31c7e01b6501f69
Author: Ulrich Drepper <drepper@redhat.com>
Date:   Tue Nov 24 18:50:32 2009 -0800

    Optimize grantpt.
    
    grantpt was performing two consecutive calls to stat with the same
    file name.  Avoid this by creating a special version of the ptsname
    function which allows to pass the stat result back to the caller.

diff --git a/ChangeLog b/ChangeLog
index 173fe78..4f74b50 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2009-11-24  Ulrich Drepper  <drepper@redhat.com>
 
+	* sysdeps/unix/grantpt.c (pts_name): Take additional parameter,
+	pass it on to __ptsname_internal.
+	(grantpt): Pass stat64 pointer to pts_name.  Remove stat call here.
+	* sysdeps/unix/sysv/linux/ptsname.c (__ptsname_internal): New function.
+	All the code from __ptsname_r but take additional parameter.  Use that
+	instead of pointer to local stat64 variable.
+	(__ptsname_r): Call __ptsname_internal with pointer to local stat64
+	variable.
+	* include/stdlib.h: Declare __ptsname_internal.
+
 	* sysdeps/unix/grantpt.c (grantpt): Use CLOSE_ALL_FDS is available
 	before the exec.
 	* sysdeps/unix/sysv/linux/grantpt.c: New file.
diff --git a/include/stdlib.h b/include/stdlib.h
index d90e6ff..f540bec 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -9,6 +9,7 @@
 
 /* Now define the internal interfaces.  */
 #ifndef __Need_M_And_C
+# include <sys/stat.h>
 
 __BEGIN_DECLS
 
@@ -77,6 +78,8 @@ extern int __clearenv (void);
 extern char *__canonicalize_file_name (__const char *__name);
 extern char *__realpath (__const char *__name, char *__resolved);
 extern int __ptsname_r (int __fd, char *__buf, size_t __buflen);
+extern int __ptsname_internal (int fd, char *buf, size_t buflen,
+			       struct stat64 *stp);
 extern int __getpt (void);
 extern int __posix_openpt (int __oflag);
 
diff --git a/sysdeps/unix/grantpt.c b/sysdeps/unix/grantpt.c
index 2a7a963..260e827 100644
--- a/sysdeps/unix/grantpt.c
+++ b/sysdeps/unix/grantpt.c
@@ -38,7 +38,7 @@
    this buffer, a sufficiently long buffer is allocated using malloc,
    and returned in PTS.  0 is returned upon success, -1 otherwise.  */
 static int
-pts_name (int fd, char **pts, size_t buf_len)
+pts_name (int fd, char **pts, size_t buf_len, struct stat64 *stp)
 {
   int rv;
   char *buf = *pts;
@@ -49,7 +49,7 @@ pts_name (int fd, char **pts, size_t buf_len)
 
       if (buf_len)
 	{
-	  rv = __ptsname_r (fd, buf, buf_len);
+	  rv = __ptsname_internal (fd, buf, buf_len, stp);
 	  if (rv != 0)
 	    {
 	      if (rv == ENOTTY)
@@ -107,8 +107,9 @@ grantpt (int fd)
   char _buf[512];
 #endif
   char *buf = _buf;
+  struct stat64 st;
 
-  if (__builtin_expect (pts_name (fd, &buf, sizeof (_buf)), 0))
+  if (__builtin_expect (pts_name (fd, &buf, sizeof (_buf), &st), 0))
     {
       int save_errno = errno;
 
@@ -127,10 +128,6 @@ grantpt (int fd)
        return -1;
     }
 
-  struct stat64 st;
-  if (__xstat64 (_STAT_VER, buf, &st) < 0)
-    goto cleanup;
-
   /* Make sure that we own the device.  */
   uid_t uid = __getuid ();
   if (st.st_uid != uid)
diff --git a/sysdeps/unix/sysv/linux/ptsname.c b/sysdeps/unix/sysv/linux/ptsname.c
index 9c364b1..ba7c791 100644
--- a/sysdeps/unix/sysv/linux/ptsname.c
+++ b/sysdeps/unix/sysv/linux/ptsname.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
 
@@ -67,14 +67,10 @@ ptsname (int fd)
 }
 
 
-/* Store at most BUFLEN characters of the pathname of the slave pseudo
-   terminal associated with the master FD is open on in BUF.
-   Return 0 on success, otherwise an error number.  */
 int
-__ptsname_r (int fd, char *buf, size_t buflen)
+__ptsname_internal (int fd, char *buf, size_t buflen, struct stat64 *stp)
 {
   int save_errno = errno;
-  struct stat64 st;
   unsigned int ptyno;
 
   if (buf == NULL)
@@ -93,7 +89,7 @@ __ptsname_r (int fd, char *buf, size_t buflen)
   if (__ioctl (fd, TIOCGPTN, &ptyno) == 0)
     {
       /* Buffer we use to print the number in.  For a maximum size for
-         `int' of 8 bytes we never need more than 20 digits.  */
+	 `int' of 8 bytes we never need more than 20 digits.  */
       char numbuf[21];
       const char *devpts = _PATH_DEVPTS;
       const size_t devptslen = strlen (_PATH_DEVPTS);
@@ -121,20 +117,20 @@ __ptsname_r (int fd, char *buf, size_t buflen)
 	  return ERANGE;
 	}
 
-      if (__fxstat64 (_STAT_VER, fd, &st) < 0)
+      if (__fxstat64 (_STAT_VER, fd, stp) < 0)
 	return errno;
 
       /* Check if FD really is a master pseudo terminal.  */
-      if (! MASTER_P (st.st_rdev))
+      if (! MASTER_P (stp->st_rdev))
 	{
 	  __set_errno (ENOTTY);
 	  return ENOTTY;
 	}
 
-      ptyno = minor (st.st_rdev);
+      ptyno = minor (stp->st_rdev);
       /* This is for the old BSD pseudo terminals.  As of Linux
-         2.1.115 these are no longer supported.  */
-      if (major (st.st_rdev) == 4)
+	 2.1.115 these are no longer supported.  */
+      if (major (stp->st_rdev) == 4)
 	ptyno -= 128;
 
       if (ptyno / 16 >= strlen (__libc_ptyname1))
@@ -149,12 +145,12 @@ __ptsname_r (int fd, char *buf, size_t buflen)
       p[2] = '\0';
     }
 
-  if (__xstat64 (_STAT_VER, buf, &st) < 0)
+  if (__xstat64 (_STAT_VER, buf, stp) < 0)
     return errno;
 
   /* Check if the name we're about to return really corresponds to a
      slave pseudo terminal.  */
-  if (! S_ISCHR (st.st_mode) || ! SLAVE_P (st.st_rdev))
+  if (! S_ISCHR (stp->st_mode) || ! SLAVE_P (stp->st_rdev))
     {
       /* This really is a configuration problem.  */
       __set_errno (ENOTTY);
@@ -164,4 +160,15 @@ __ptsname_r (int fd, char *buf, size_t buflen)
   __set_errno (save_errno);
   return 0;
 }
+
+
+/* Store at most BUFLEN characters of the pathname of the slave pseudo
+   terminal associated with the master FD is open on in BUF.
+   Return 0 on success, otherwise an error number.  */
+int
+__ptsname_r (int fd, char *buf, size_t buflen)
+{
+  struct stat64 st;
+  return __ptsname_internal (fd, buf, buflen, &st);
+}
 weak_alias (__ptsname_r, ptsname_r)

http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=0f622686af3ae5a8f03dae886b08c260b38bda16

commit 0f622686af3ae5a8f03dae886b08c260b38bda16
Author: Ulrich Drepper <drepper@redhat.com>
Date:   Tue Nov 24 18:47:26 2009 -0800

    Avoid local PLTs.

diff --git a/sysdeps/unix/sysv/linux/grantpt.c b/sysdeps/unix/sysv/linux/grantpt.c
index 6305ed4..f2fc60f 100644
--- a/sysdeps/unix/sysv/linux/grantpt.c
+++ b/sysdeps/unix/sysv/linux/grantpt.c
@@ -15,11 +15,11 @@
 static void
 close_all_fds (void)
 {
-  DIR *dir = opendir ("/proc/self/fd");
+  DIR *dir = __opendir ("/proc/self/fd");
   if (dir != NULL)
     {
       struct dirent64 *d;
-      while ((d = readdir64 (dir)) != NULL)
+      while ((d = __readdir64 (dir)) != NULL)
 	if (isdigit (d->d_name[0]))
 	  {
 	    char *endp;
@@ -28,7 +28,7 @@ close_all_fds (void)
 	      close_not_cancel_no_status (fd);
 	  }
 
-      closedir (dir);
+      __closedir (dir);
 
       int nullfd = open_not_cancel_2 (_PATH_DEVNULL, O_RDONLY);
       assert (nullfd == STDIN_FILENO);

http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=139ee080b6b428240bf49f3e6361f3ac729f891a

commit 139ee080b6b428240bf49f3e6361f3ac729f891a
Author: Ulrich Drepper <drepper@redhat.com>
Date:   Tue Nov 24 18:24:14 2009 -0800

    Prevent unintended file desriptor leak in grantpt.
    
    The pt_chown program is completely transparently called.  It might
    not be able to live with the various file descriptors the program
    has open at the time of the call (e.g., under SELinux).  Close all
    but the needed descriptor and connect stdin, stdout, and stderr
    with /dev/null.  pt_chown shouldn't print anything when called to
    do real work.

diff --git a/ChangeLog b/ChangeLog
index c78e190..173fe78 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2009-11-24  Ulrich Drepper  <drepper@redhat.com>
 
+	* sysdeps/unix/grantpt.c (grantpt): Use CLOSE_ALL_FDS is available
+	before the exec.
+	* sysdeps/unix/sysv/linux/grantpt.c: New file.
+	* login/programs/pt_chown.c (main): Don't print message on errors
+	when doing real work.
+
 	* sysdeps/unix/grantpt.c (grantpt): Only get tty group information
 	once.
 
diff --git a/login/programs/pt_chown.c b/login/programs/pt_chown.c
index 7e279a5..4c36f2c 100644
--- a/login/programs/pt_chown.c
+++ b/login/programs/pt_chown.c
@@ -154,8 +154,7 @@ main (int argc, char *argv[])
 # define ncap_list (sizeof (cap_list) / sizeof (cap_list[0]))
 	  cap_t caps = cap_init ();
 	  if (caps == NULL)
-	    error (FAIL_ENOMEM, errno,
-		   _("Failed to initialize drop of capabilities"));
+	    return FAIL_ENOMEM;
 
 	  /* There is no reason why these should not work.  */
 	  cap_set_flag (caps, CAP_PERMITTED, ncap_list, cap_list, CAP_SET);
@@ -166,7 +165,7 @@ main (int argc, char *argv[])
 	  cap_free (caps);
 
 	  if (__builtin_expect (res != 0, 0))
-	    error (FAIL_EXEC, errno, _("cap_set_proc failed"));
+	    return FAIL_EXEC;
 	}
 #endif
 
diff --git a/sysdeps/unix/grantpt.c b/sysdeps/unix/grantpt.c
index e140fb2..2a7a963 100644
--- a/sysdeps/unix/grantpt.c
+++ b/sysdeps/unix/grantpt.c
@@ -194,6 +194,10 @@ grantpt (int fd)
 	if (__dup2 (fd, PTY_FILENO) < 0)
 	  _exit (FAIL_EBADF);
 
+#ifdef CLOSE_ALL_FDS
+      CLOSE_ALL_FDS ();
+#endif
+
       execle (_PATH_PT_CHOWN, basename (_PATH_PT_CHOWN), NULL, NULL);
       _exit (FAIL_EXEC);
     }
diff --git a/sysdeps/unix/sysv/linux/grantpt.c b/sysdeps/unix/sysv/linux/grantpt.c
new file mode 100644
index 0000000..6305ed4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/grantpt.c
@@ -0,0 +1,42 @@
+#include <assert.h>
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "not-cancel.h"
+#include "pty-private.h"
+
+
+/* Close all file descriptors except the one specified.  */
+static void
+close_all_fds (void)
+{
+  DIR *dir = opendir ("/proc/self/fd");
+  if (dir != NULL)
+    {
+      struct dirent64 *d;
+      while ((d = readdir64 (dir)) != NULL)
+	if (isdigit (d->d_name[0]))
+	  {
+	    char *endp;
+	    long int fd = strtol (d->d_name, &endp, 10);
+	    if (*endp == '\0' && fd != PTY_FILENO && fd != dirfd (dir))
+	      close_not_cancel_no_status (fd);
+	  }
+
+      closedir (dir);
+
+      int nullfd = open_not_cancel_2 (_PATH_DEVNULL, O_RDONLY);
+      assert (nullfd == STDIN_FILENO);
+      nullfd = open_not_cancel_2 (_PATH_DEVNULL, O_WRONLY);
+      assert (nullfd == STDOUT_FILENO);
+      __dup2 (STDOUT_FILENO, STDERR_FILENO);
+    }
+}
+#define CLOSE_ALL_FDS() close_all_fds()
+
+#include <sysdeps/unix/grantpt.c>

http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=fa214705b957d20621cb1190b467aa88bc9b69a3

commit fa214705b957d20621cb1190b467aa88bc9b69a3
Author: Ulrich Drepper <drepper@redhat.com>
Date:   Tue Nov 24 18:22:30 2009 -0800

    Once again forgot to add new test file.

diff --git a/nptl/tst-sem13.c b/nptl/tst-sem13.c
new file mode 100644
index 0000000..8756b22
--- /dev/null
+++ b/nptl/tst-sem13.c
@@ -0,0 +1,46 @@
+#include <errno.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <internaltypes.h>
+
+
+static int
+do_test (void)
+{
+  union
+  {
+    sem_t s;
+    struct new_sem ns;
+  } u;
+
+  if (sem_init (&u.s, 0, 0) != 0)
+    {
+      puts ("sem_init failed");
+      return 1;
+    }
+
+  struct timespec ts = { 0, 1000000001 };	/* Invalid.  */
+  errno = 0;
+  if (sem_timedwait (&u.s, &ts) >= 0)
+    {
+      puts ("sem_timedwait did not fail");
+      return 1;
+    }
+  if (errno != EINVAL)
+    {
+      puts ("sem_timedwait did not fail with EINVAL");
+      return 1;
+    }
+  if (u.ns.nwaiters != 0)
+    {
+      puts ("nwaiters modified");
+      return 1;
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"

http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=21f2c22320c00c1627dd734794af7353ad7637b2

commit 21f2c22320c00c1627dd734794af7353ad7637b2
Author: Ulrich Drepper <drepper@redhat.com>
Date:   Tue Nov 24 17:50:27 2009 -0800

    Don't get tty group info multiple times in grantpt.
    
    This is a minor optimization.  The tty group mustn't change so a
    successful call to getgrnam will always return the same information.
    Cache it and reuse it.

diff --git a/ChangeLog b/ChangeLog
index dd68e5b..c78e190 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2009-11-24  Ulrich Drepper  <drepper@redhat.com>
 
+	* sysdeps/unix/grantpt.c (grantpt): Only get tty group information
+	once.
+
 	* csu/elf-init.c (__libc_csu_irel): New function.  Code to perform
 	irel relocations split out from...
 	(__libc_csu_init): ...here.
diff --git a/sysdeps/unix/grantpt.c b/sysdeps/unix/grantpt.c
index 8c299e9..e140fb2 100644
--- a/sysdeps/unix/grantpt.c
+++ b/sysdeps/unix/grantpt.c
@@ -107,14 +107,6 @@ grantpt (int fd)
   char _buf[512];
 #endif
   char *buf = _buf;
-  struct stat64 st;
-  char *grtmpbuf;
-  struct group grbuf;
-  size_t grbuflen = __sysconf (_SC_GETGR_R_SIZE_MAX);
-  struct group *p;
-  uid_t uid;
-  gid_t gid;
-  pid_t pid;
 
   if (__builtin_expect (pts_name (fd, &buf, sizeof (_buf)), 0))
     {
@@ -126,34 +118,46 @@ grantpt (int fd)
 	return -1;
 
        /* If the filedescriptor is no TTY, grantpt has to set errno
-          to EINVAL.  */
+	  to EINVAL.  */
        if (save_errno == ENOTTY)
-         __set_errno (EINVAL);
+	 __set_errno (EINVAL);
        else
 	 __set_errno (save_errno);
 
        return -1;
     }
 
+  struct stat64 st;
   if (__xstat64 (_STAT_VER, buf, &st) < 0)
     goto cleanup;
 
   /* Make sure that we own the device.  */
-  uid = __getuid ();
+  uid_t uid = __getuid ();
   if (st.st_uid != uid)
     {
       if (__chown (buf, uid, st.st_gid) < 0)
 	goto helper;
     }
 
-  /* Get the group ID of the special `tty' group.  */
-  if (grbuflen == (size_t) -1L)
-    /* `sysconf' does not support _SC_GETGR_R_SIZE_MAX.
-       Try a moderate value.  */
-    grbuflen = 1024;
-  grtmpbuf = (char *) __alloca (grbuflen);
-  __getgrnam_r (TTY_GROUP, &grbuf, grtmpbuf, grbuflen, &p);
-  gid = p ? p->gr_gid : __getgid ();
+  static int tty_gid = -1;
+  if (__builtin_expect (tty_gid == -1, 0))
+    {
+      char *grtmpbuf;
+      struct group grbuf;
+      size_t grbuflen = __sysconf (_SC_GETGR_R_SIZE_MAX);
+      struct group *p;
+
+      /* Get the group ID of the special `tty' group.  */
+      if (grbuflen == (size_t) -1L)
+	/* `sysconf' does not support _SC_GETGR_R_SIZE_MAX.
+	   Try a moderate value.  */
+	grbuflen = 1024;
+      grtmpbuf = (char *) __alloca (grbuflen);
+      __getgrnam_r (TTY_GROUP, &grbuf, grtmpbuf, grbuflen, &p);
+      if (p != NULL)
+	tty_gid = p->gr_gid;
+    }
+  gid_t gid = tty_gid == -1 ? __getgid () : tty_gid;
 
   /* Make sure the group of the device is that special group.  */
   if (st.st_gid != gid)
@@ -174,9 +178,9 @@ grantpt (int fd)
   goto cleanup;
 
   /* We have to use the helper program.  */
- helper:
+ helper:;
 
-  pid = __fork ();
+  pid_t pid = __fork ();
   if (pid == -1)
     goto cleanup;
   else if (pid == 0)

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                         |   19 ++++++++++++
 include/stdlib.h                  |    3 ++
 login/programs/pt_chown.c         |    5 +--
 nptl/tst-sem13.c                  |   46 ++++++++++++++++++++++++++++
 sysdeps/unix/grantpt.c            |   59 ++++++++++++++++++++-----------------
 sysdeps/unix/sysv/linux/grantpt.c |   42 ++++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/ptsname.c |   35 +++++++++++++---------
 7 files changed, 165 insertions(+), 44 deletions(-)
 create mode 100644 nptl/tst-sem13.c
 create mode 100644 sysdeps/unix/sysv/linux/grantpt.c


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]