This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
[PATCH] Make getlogin_r thread safe
- From: Steve Munroe <sjmunroe at vnet dot ibm dot com>
- To: libc-alpha at sources dot redhat dot com
- Cc: bergner at us dot ibm dot com
- Date: Wed, 9 Oct 2002 16:34:37 -0500
- Subject: [PATCH] Make getlogin_r thread safe
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)
{