Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 2003d1abfa0c20ee77815f0da33e2c1c > files > 201

glibc-2.5-49.el5_5.5.src.rpm

2008-12-13  Klaus Dittrich  <kladit@arcor.de>

	* login/utmp_file.c (pututline_file): Replace call to dup2 with
	libc internal symbol __dup2 to avoid access through the PLT.

2008-11-29  Ulrich Drepper  <drepper@redhat.com>

	* login/utmp_file.c (file_writable): New variable.
	(setutent_file): Don't try to open file for writing.
	(pututline_file): Before writing, make descriptor writable if
	necessary.

--- libc/login/utmp_file.c	14 Aug 2008 04:22:59 -0000	1.22
+++ libc/login/utmp_file.c	23 Dec 2008 16:49:43 -0000	1.24
@@ -34,6 +34,7 @@
 
 /* Descriptor for the file and position.  */
 static int file_fd = -1;
+static bool file_writable;
 static off64_t file_offset;
 
 /* Cache for the last read entry.  */
@@ -136,21 +137,16 @@ setutent_file (void)
   if (file_fd < 0)
     {
       const char *file_name;
-      int result;
 
       file_name = TRANSFORM_UTMP_FILE_NAME (__libc_utmp_file_name);
 
-      file_fd = open_not_cancel_2 (file_name, O_RDWR | O_LARGEFILE);
+      file_writable = false;
+      file_fd = open_not_cancel_2 (file_name, O_RDONLY | O_LARGEFILE);
       if (file_fd == -1)
-	{
-	  /* Hhm, read-write access did not work.  Try read-only.  */
-	  file_fd = open_not_cancel_2 (file_name, O_RDONLY | O_LARGEFILE);
-	  if (file_fd == -1)
-	    return 0;
-	}
+	return 0;
 
       /* We have to make sure the file is `closed on exec'.  */
-      result = fcntl_not_cancel (file_fd, F_GETFD, 0);
+      int result = fcntl_not_cancel (file_fd, F_GETFD, 0);
       if (result >= 0)
 	result = fcntl_not_cancel (file_fd, F_SETFD, result | FD_CLOEXEC);
       if (result == -1)
@@ -373,6 +369,36 @@ pututline_file (const struct utmp *data)
 
   assert (file_fd >= 0);
 
+  if (! file_writable)
+    {
+      /* We must make the file descriptor writable before going on.  */
+      const char *file_name = TRANSFORM_UTMP_FILE_NAME (__libc_utmp_file_name);
+
+      int new_fd = open_not_cancel_2 (file_name, O_RDWR | O_LARGEFILE);
+      if (new_fd == -1)
+	return NULL;
+
+      /* We have to make sure the file is `closed on exec'.  */
+      int result = fcntl_not_cancel (file_fd, F_GETFD, 0);
+      if (result >= 0)
+	result = fcntl_not_cancel (file_fd, F_SETFD, result | FD_CLOEXEC);
+
+      if (result == -1)
+	{
+	  close_not_cancel_no_status (file_fd);
+	  return NULL;
+	}
+
+      if (__lseek64 (new_fd, __lseek64 (file_fd, 0, SEEK_CUR), SEEK_SET) == -1
+	  || __dup2 (new_fd, file_fd) < 0)
+	{
+	  close_not_cancel_no_status (new_fd);
+	  return NULL;
+	}
+      close_not_cancel_no_status (new_fd);
+      file_writable = true;
+    }
+
   /* Find the correct place to insert the data.  */
   if (file_offset > 0
       && (