about summary refs log tree commit diff
path: root/sysdeps/unix/sysv
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2009-11-24 18:24:14 -0800
committerPetr Baudis <pasky@ucw.cz>2009-12-04 14:50:39 +0100
commit65a27b0b41a8ec07407ad0415fd0963917c59941 (patch)
treee56304e1f744660741d50a9d54a1d777ca2ce20e /sysdeps/unix/sysv
parent4f9d265e05056df279186d033af75352a679685f (diff)
downloadglibc-65a27b0b41a8ec07407ad0415fd0963917c59941.tar.gz
glibc-65a27b0b41a8ec07407ad0415fd0963917c59941.tar.xz
glibc-65a27b0b41a8ec07407ad0415fd0963917c59941.zip
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.

(cherry picked from commit 139ee080b6b428240bf49f3e6361f3ac729f891a)
Diffstat (limited to 'sysdeps/unix/sysv')
-rw-r--r--sysdeps/unix/sysv/linux/grantpt.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/grantpt.c b/sysdeps/unix/sysv/linux/grantpt.c
new file mode 100644
index 0000000000..6305ed4944
--- /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>