Bug#729746: MAXLOGNAME increased (17 -> 32)
On 25/11/2013 14:56, Petr Salinger wrote:
> The getlogin_r is not thread safe, as it uses the same buffer as getlogin.
This should fix it, I think. It still updates the buffer (for the sake
of getlogin) but doesn't rely on it.
Also, I think the ERANGE check can be removed when we drop support for
pre-9.2.
--
Robert Millan
Index: getlogin_r.c
===================================================================
--- getlogin_r.c (revision 5163)
+++ getlogin_r.c (working copy)
@@ -25,11 +25,9 @@
#include <sys/param.h>
#include <sysdep.h>
-/* Cache the system call's return value. */
-char *__getlogin_cache;
-/* The kernel never returns more than MAXLOGNAME bytes, therefore we don't
- need more than that either. */
-char __getlogin_cache_room[MAXLOGNAME];
+/* Defined in getlogin.c. */
+extern char *__getlogin_cache;
+extern char __getlogin_cache_room[MAXLOGNAME];
extern int __syscall_getlogin (char *__name, size_t __name_len);
libc_hidden_proto (__syscall_getlogin)
@@ -45,20 +43,28 @@
{
size_t len;
- if (__getlogin_cache == NULL)
- {
- if (INLINE_SYSCALL (getlogin, 2, __getlogin_cache_room, MAXLOGNAME) < 0)
+ if (INLINE_SYSCALL (getlogin, 2, name, name_len) < 0)
return errno;
/* The system call should return a NULL terminated name. */
- if (__memchr (__getlogin_cache_room, '\0', MAXLOGNAME) == NULL)
+ if (__memchr (name, '\0', name_len) == NULL)
abort ();
- __getlogin_cache = __getlogin_cache_room;
- }
- len = strlen (__getlogin_cache);
+ len = strlen (name);
+
+ /* FIXME: recent kernels (r243021) already check this (and set ERANGE). */
if (__builtin_expect (len < name_len, 1))
{
- memcpy (name, __getlogin_cache, len + 1);
+ /* We update the cache only for the sake of getlogin.c. We can't use it
+ ourselves since it would break thread-safety. */
+
+ /* Upstream has increased MAXLOGNAME in the kernel before (r243023).
+ Be safe rather than sorry. */
+ if (len + 1 <= sizeof (__getlogin_cache_room))
+ {
+ /* Not thread-safe, but the only consumer (getlogin.c) doesn't care. */
+ memcpy (__getlogin_cache, name, len + 1);
+ __getlogin_cache = __getlogin_cache_room;
+ }
return 0;
}
else
Index: getlogin.c
===================================================================
--- getlogin.c (revision 5151)
+++ getlogin.c (working copy)
@@ -24,9 +24,11 @@
#include <sys/param.h>
#include <sysdep.h>
-/* Defined in getlogin_r.c. */
-extern char *__getlogin_cache;
-extern char __getlogin_cache_room[MAXLOGNAME];
+/* Cache the system call's return value. */
+char *__getlogin_cache;
+/* The kernel never returns more than MAXLOGNAME bytes, therefore we don't
+ need more than that either. */
+char __getlogin_cache_room[MAXLOGNAME];
extern int __syscall_getlogin (char *__name, size_t __name_len);
libc_hidden_proto (__syscall_getlogin)
Reply to: