This is the mail archive of the libc-alpha@sources.redhat.com 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]

[PATCH] getlogin_r thread safety


Found this when one of our users complained that getlogin_r was not thread 
safe. Currently on glibc-2.2.4, 2.2.5, and 2.3 concurrent calls to getlogin_r may
fail because the utmp file may be repositioned between the __setutent() call
int getlogin_r and the file lock surrounding the read loop in getutline_r_file().

This can cause getutline_r_file() to read pass end of the file without finding a
matching utmp record, since it is already positioned pass the record it needs.
In this case getutline_r_file() sets file_offset to -1 (an EOF marker) and 
returns with error.  In a threaded environemnt this can cause a secondary 
failure, since another thread may find file_offset set to -1 just after it called
__setutent().

The patch adds a test, immediately following the file lock, and insures that 
the read loop starts at the begining of the file. I have tested this on
both glibc-2.2.5 and 2.3 and make check runs successfully.

2002-10-09   Steven Munroe  <sjmunroe@us.ibm.com>

	* sysdeps/generic/utmp_file.c (getutline_r_file) : If file_offset not zero
	lseek to the begining of utmp file.

diff -rupPN libc23-cvstip-20021002/sysdeps/generic/utmp_file.c libc23/sysdeps/generic/utmp_file.c
--- libc23-cvstip-20021002/sysdeps/generic/utmp_file.c	Mon Sep 30 17:28:18 2002
+++ libc23/sysdeps/generic/utmp_file.c	Wed Oct  9 15:58:41 2002
@@ -328,6 +328,16 @@ getutline_r_file (const struct utmp *lin
       *result = NULL;
       LOCKING_FAILED ();
     }
+    
+  /* Another thread may have moved the file_offset between this threads 
+     __setutend() call and this point.  This may cause this threads 
+     getlogin_r to fail.  So insure that this function starts 
+     reading from the start of the file.  */
+  if (file_offset != 0l)
+    {
+      __lseek64 (file_fd, 0, SEEK_SET);
+      file_offset = 0;
+    }
 
   while (1)
     {


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