public inbox for glibc-cvs@sourceware.org
help / color / mirror / Atom feed
* [glibc/azanella/y2038] login: Use 64-bit time on struct lastlog
@ 2020-07-30 13:28 Adhemerval Zanella
  0 siblings, 0 replies; 8+ messages in thread
From: Adhemerval Zanella @ 2020-07-30 13:28 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=18e937f4d69f1624835de02dd8c762a99b71b457

commit 18e937f4d69f1624835de02dd8c762a99b71b457
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Wed Jul 29 16:18:13 2020 -0300

    login: Use 64-bit time on struct lastlog
    
    It is not used directly on any symbol, so there is no need to add
    compat ones.

Diff:
---
 bits/types/struct_lastlog.h                        |  4 +--
 sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h | 34 ----------------------
 2 files changed, 2 insertions(+), 36 deletions(-)

diff --git a/bits/types/struct_lastlog.h b/bits/types/struct_lastlog.h
index 122a44abd0..6882015d7c 100644
--- a/bits/types/struct_lastlog.h
+++ b/bits/types/struct_lastlog.h
@@ -24,8 +24,8 @@
    previous logins.  */
 struct lastlog
   {
-#if __WORDSIZE_TIME64_COMPAT32
-    int32_t ll_time;
+#if __TIMESIZE != 64
+    int64_t ll_time;
 #else
     __time_t ll_time;
 #endif
diff --git a/sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h b/sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h
deleted file mode 100644
index 715e8f1b74..0000000000
--- a/sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* The 'struct lastlog' type.
-   Copyright (C) 2020 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#ifndef _UTMP_H
-# error "Never include <bits/struct_lastlog.h> directly; use <utmp.h> instead."
-#endif
-
-/* The structure describing an entry in the database of
-   previous logins.  */
-struct lastlog
-  {
-#if __WORDSIZE == 32
-    int64_t ll_time;
-#else
-    __time_t ll_time;
-#endif
-    char ll_line[UT_LINESIZE];
-    char ll_host[UT_HOSTSIZE];
-  };


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [glibc/azanella/y2038] login: Use 64-bit time on struct lastlog
@ 2021-03-04 17:37 Adhemerval Zanella
  0 siblings, 0 replies; 8+ messages in thread
From: Adhemerval Zanella @ 2021-03-04 17:37 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=a31910301cf6fdbb85d6eb07ad27d31bbef701f8

commit a31910301cf6fdbb85d6eb07ad27d31bbef701f8
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Tue Aug 4 10:50:02 2020 -0300

    login: Use 64-bit time on struct lastlog
    
    The new struct has the same size on both 32-bit and 64-bit
    architectures.  As for utmp{x} 64-bit time_t support, a new file name
    is defined for _PATH_LASTLOG.
    
    Also two new symbols are added that read/write 'struct lastlog'
    entries, 'lastlog_read' and 'lastlog_write'.  Both are GNU extensions
    and handle the 32-bit entry operation if the argument is the old
    _PATH_LASTLOG path.
    
    Different than utmp{x}, no concurrent access is done (such as
    advisory locking).  I modeled these function on how program that
    access lastlog file uses (such as shadow-utils and util-linux).
    
    The s390 is the only architecture that already defined the
    'struct lastlog' with 64-bit time_t and to handle s390 has a specific
    lastlog-compat.h header where 'is_path_lastlog_compat' already
    return false (thus making both lastlog_read and lastlog_write
    always read/write registers with 64-bit ll_time).
    
    It also fixes BZ#25844 by adding the __attribute_nonstring__ on
    ll_line and ll_host.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.

Diff:
---
 bits/types/struct_lastlog.h                        | 10 +--
 login/Makefile                                     |  5 +-
 login/Versions                                     |  2 +
 .../struct_lastlog.h => login/lastlog-compat.h     | 27 ++++----
 login/lastlog_read.c                               | 71 +++++++++++++++++++
 login/lastlog_write.c                              | 59 ++++++++++++++++
 login/tst-lastlog.c                                | 79 ++++++++++++++++++++++
 login/tst-lastlog.root/tst-lastlog.script          |  6 ++
 login/utmp.h                                       | 11 +++
 sysdeps/generic/paths.h                            |  3 +-
 sysdeps/mach/hurd/i386/libc.abilist                |  2 +
 sysdeps/unix/sysv/linux/aarch64/libc.abilist       |  2 +
 sysdeps/unix/sysv/linux/alpha/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/arc/libc.abilist           |  2 +
 sysdeps/unix/sysv/linux/arm/be/libc.abilist        |  2 +
 sysdeps/unix/sysv/linux/arm/le/libc.abilist        |  2 +
 sysdeps/unix/sysv/linux/csky/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/hppa/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/i386/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/ia64/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/microblaze/be/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/microblaze/le/libc.abilist |  2 +
 .../unix/sysv/linux/mips/mips32/fpu/libc.abilist   |  2 +
 .../unix/sysv/linux/mips/mips32/nofpu/libc.abilist |  2 +
 .../unix/sysv/linux/mips/mips64/n32/libc.abilist   |  2 +
 .../unix/sysv/linux/mips/mips64/n64/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/nios2/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/paths.h                    |  3 +-
 .../sysv/linux/powerpc/powerpc32/fpu/libc.abilist  |  2 +
 .../linux/powerpc/powerpc32/nofpu/libc.abilist     |  2 +
 .../sysv/linux/powerpc/powerpc64/be/libc.abilist   |  2 +
 .../sysv/linux/powerpc/powerpc64/le/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist    |  2 +
 sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist    |  2 +
 sysdeps/unix/sysv/linux/s390/lastlog-compat.h      | 38 +++++++++++
 sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist  |  2 +
 sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist  |  2 +
 sysdeps/unix/sysv/linux/sh/be/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/sh/le/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/x86_64/64/libc.abilist     |  2 +
 sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist    |  2 +
 45 files changed, 357 insertions(+), 23 deletions(-)

diff --git a/bits/types/struct_lastlog.h b/bits/types/struct_lastlog.h
index 67ffec1b08..8c87958bec 100644
--- a/bits/types/struct_lastlog.h
+++ b/bits/types/struct_lastlog.h
@@ -24,11 +24,7 @@
    previous logins.  */
 struct lastlog
 {
-#if __WORDSIZE_TIME64_COMPAT32
-  int32_t ll_time;
-#else
-  __time_t ll_time;
-#endif
-  char ll_line[UT_LINESIZE];
-  char ll_host[UT_HOSTSIZE];
+  int64_t ll_time;
+  char ll_line[UT_LINESIZE] __attribute_nonstring__;
+  char ll_host[UT_HOSTSIZE] __attribute_nonstring__;
 };
diff --git a/login/Makefile b/login/Makefile
index b5569683fa..4b5a3f0d63 100644
--- a/login/Makefile
+++ b/login/Makefile
@@ -31,7 +31,8 @@ headers	:= utmp.h bits/utmp.h lastlog.h pty.h \
 routines := getlogin getlogin_r setlogin getlogin_r_chk \
 	    getutent getutent_r getutid getutline getutid_r getutline_r \
 	    utmp_file utmpname updwtmp getpt grantpt unlockpt ptsname \
-	    ptsname_r_chk utmp32 utmpx32 utmp-convert
+	    ptsname_r_chk utmp32 utmpx32 utmp-convert \
+	    lastlog_read lastlog_write
 
 CFLAGS-grantpt.c += -DLIBEXECDIR='"$(libexecdir)"'
 
@@ -50,7 +51,7 @@ tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \
   tst-pututxline-lockfail tst-pututxline-cache
 
 tests-container-internal := tst-utmp32
-tests-container := tst-utmp-default
+tests-container := tst-utmp-default tst-lastlog
 
 # Build the -lutil library with these extra functions.
 extra-libs      := libutil
diff --git a/login/Versions b/login/Versions
index d28ecdca9f..5751fdcb71 100644
--- a/login/Versions
+++ b/login/Versions
@@ -57,6 +57,8 @@ libc {
     getutxent;
     getutxid;
     getutxline;
+    lastlog_read;
+    lastlog_write;
     pututline;
     pututxline;
     updwtmp;
diff --git a/sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h b/login/lastlog-compat.h
similarity index 74%
rename from sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h
rename to login/lastlog-compat.h
index 1faa472ec8..687774a21e 100644
--- a/sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h
+++ b/login/lastlog-compat.h
@@ -1,4 +1,4 @@
-/* The 'struct lastlog' type.
+/* Compat lastlog definitions.
    Copyright (C) 2020 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,19 +16,22 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#ifndef _UTMP_H
-# error "Never include <bits/struct_lastlog.h> directly; use <utmp.h> instead."
-#endif
+#ifndef _LASTLOG_COMPAT_H
+#define _LASTLOG_COMPAT_H 1
+
+#include <string.h>
 
-/* The structure describing an entry in the database of
-   previous logins.  */
-struct lastlog
+struct lastlog_compat
 {
-#if __WORDSIZE == 32
-  int64_t ll_time;
-#else
-  __time_t ll_time;
-#endif
+  int32_t ll_time;
   char ll_line[UT_LINESIZE];
   char ll_host[UT_HOSTSIZE];
 };
+
+static inline bool
+is_path_lastlog_compat (const char *file)
+{
+  return strcmp (file, "/var/log/lastlog") == 0;
+}
+
+#endif
diff --git a/login/lastlog_read.c b/login/lastlog_read.c
new file mode 100644
index 0000000000..e2c6e82a15
--- /dev/null
+++ b/login/lastlog_read.c
@@ -0,0 +1,71 @@
+/* Read a lastlog entry.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <utmp.h>
+#include <stdbool.h>
+#include <not-cancel.h>
+#include <lastlog-compat.h>
+
+ssize_t
+lastlog_read (const char *file, uid_t uid, struct lastlog *ll)
+{
+  int fd = __open_nocancel (file, O_RDONLY | O_LARGEFILE | O_CLOEXEC);
+  if (fd == -1)
+    return -1;
+
+  size_t llsize;
+  struct lastlog_compat llcompat;
+  void *data;
+
+  if (is_path_lastlog_compat (file))
+    {
+      llsize = sizeof (struct lastlog_compat);
+      data = &llcompat;
+    }
+  else
+    {
+      llsize = sizeof (struct lastlog);
+      data = ll;
+    }
+
+  off64_t off = llsize * uid;
+  ssize_t r = __pread64_nocancel (fd, data, llsize, off);
+  __close_nocancel_nostatus (fd);
+
+  if (r == llsize && data == &llcompat)
+    {
+      ll->ll_time = llcompat.ll_time;
+      memcpy (ll->ll_line, llcompat.ll_line, UT_LINESIZE);
+      memcpy (ll->ll_host, llcompat.ll_host, UT_HOSTSIZE);
+    }
+
+  if (r == llsize)
+    {
+      if (data == &llcompat)
+	{
+	  ll->ll_time = llcompat.ll_time;
+	  memcpy (ll->ll_line, llcompat.ll_line, UT_LINESIZE);
+	  memcpy (ll->ll_host, llcompat.ll_host, UT_HOSTSIZE);
+	}
+      /* We need to return the expected 'struct lastlog' size in case of
+	 success.  */
+      r = sizeof (struct lastlog);
+    }
+
+  return r;
+}
diff --git a/login/lastlog_write.c b/login/lastlog_write.c
new file mode 100644
index 0000000000..f3aedcbdb7
--- /dev/null
+++ b/login/lastlog_write.c
@@ -0,0 +1,59 @@
+/* Write a lastlog entry.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <utmp.h>
+#include <stdbool.h>
+#include <not-cancel.h>
+#include <lastlog-compat.h>
+
+ssize_t
+lastlog_write (const char *file, uid_t uid, const struct lastlog *ll)
+{
+  int fd = __open_nocancel (file, O_WRONLY | O_LARGEFILE | O_CLOEXEC);
+  if (fd == -1)
+    return -1;
+
+  size_t llsize;
+  struct lastlog_compat llcompat;
+  const void *data;
+
+  if (is_path_lastlog_compat (file))
+    {
+      llcompat.ll_time = ll->ll_time;
+      memcpy (llcompat.ll_line, ll->ll_line, UT_LINESIZE);
+      memcpy (llcompat.ll_host, ll->ll_host, UT_HOSTSIZE);
+      llsize = sizeof (struct lastlog_compat);
+      data = &llcompat;
+    }
+  else
+    {
+      llsize = sizeof (struct lastlog);
+      data = ll;
+    }
+
+  off64_t off = llsize * uid;
+  ssize_t r = __pwrite64_nocancel (fd, data, llsize, off);
+  __close_nocancel_nostatus (fd);
+
+  /* We need to return the expected 'struct lastlog' size in case of
+     success.  */
+  if (r == llsize && data == &llcompat)
+    r = sizeof (struct lastlog);
+
+  return r;
+}
diff --git a/login/tst-lastlog.c b/login/tst-lastlog.c
new file mode 100644
index 0000000000..9376a6ddf4
--- /dev/null
+++ b/login/tst-lastlog.c
@@ -0,0 +1,79 @@
+/* Tests for lastlog read/write functions.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+#include <string.h>
+#include <utmp.h>
+
+#include <support/check.h>
+#include <support/temp_file.h>
+
+#include <stdio.h>
+
+static struct
+{
+  uid_t uid;
+  struct lastlog ll;
+} entry[] =
+{
+  { 0,    { .ll_time = 1000, .ll_line = "tty1" } },
+  { 1000, { .ll_time = 2000, .ll_line = "pts/0", .ll_host = "127.0.0.1" } },
+  { 20,   { .ll_time = 3000, .ll_line = "pts/1", .ll_host = "192.168.0.1" } },
+  { 30,   { .ll_time = 4000, .ll_line = "tty2" } },
+};
+const size_t entry_size = sizeof (entry) / sizeof (entry[0]);
+
+static void
+run_test (const char *filename)
+{
+  for (int n = 0; n < entry_size; n++)
+    TEST_COMPARE (lastlog_write (filename, entry[n].uid, &entry[n].ll),
+		  sizeof (struct lastlog));
+
+  for (int n = 0; n < entry_size; n++)
+    {
+      struct lastlog ll;
+      TEST_COMPARE (lastlog_read (filename, entry[n].uid, &ll),
+		    sizeof (struct lastlog));
+      TEST_COMPARE (ll.ll_time, entry[n].ll.ll_time);
+      TEST_COMPARE_BLOB (ll.ll_line, UT_LINESIZE,
+			 entry[n].ll.ll_line, UT_LINESIZE);
+      TEST_COMPARE_BLOB (ll.ll_host, UT_HOSTSIZE,
+			 entry[n].ll.ll_host, UT_HOSTSIZE);
+    }
+
+  /* Check with an non present uid.  */
+  {
+    struct lastlog ll;
+    TEST_COMPARE (lastlog_read (filename, 4000, &ll), 0);
+  }
+}
+
+static int
+do_test (void)
+{
+  /* The path triggers the read/write of compat (32-bit ll_time) entries.  */
+  run_test ("/var/run/lastlog");
+
+  /* Any other file handles new (64-bit ll_time) entries.  */
+  run_test ("/var/run/lastlog.v2");
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/login/tst-lastlog.root/tst-lastlog.script b/login/tst-lastlog.root/tst-lastlog.script
new file mode 100644
index 0000000000..ca34ce7021
--- /dev/null
+++ b/login/tst-lastlog.root/tst-lastlog.script
@@ -0,0 +1,6 @@
+mkdirp 0755 /var/run
+touch  0664 /var/run/lastlog
+touch  0664 /var/run/lastlog.v2
+
+# Must run localedef as root to write into default paths.
+su
diff --git a/login/utmp.h b/login/utmp.h
index 7fc2d5cdf1..02a445ee82 100644
--- a/login/utmp.h
+++ b/login/utmp.h
@@ -91,6 +91,17 @@ extern int getutline_r (const struct utmp *__line,
 
 #endif	/* Use misc.  */
 
+#ifdef __USE_GNU
+/* Read the struct lastlog LL with UID from file FILE.  */
+extern ssize_t lastlog_read (const char *__file, uid_t __uid,
+			     struct lastlog *__ll)
+     __THROW __nonnull ((1, 3));
+/* Write the struct lastlog LL with UID from file FILE.  */
+extern ssize_t lastlog_write (const char *__file, uid_t __uid,
+			      const struct lastlog *__ll)
+     __THROW __nonnull ((1, 3));
+#endif
+
 __END_DECLS
 
 #endif /* utmp.h  */
diff --git a/sysdeps/generic/paths.h b/sysdeps/generic/paths.h
index ab2980e14a..9321ad7294 100644
--- a/sysdeps/generic/paths.h
+++ b/sysdeps/generic/paths.h
@@ -46,7 +46,8 @@
 #define	_PATH_DRUM	"/dev/drum"
 #define	_PATH_GSHADOW	"/etc/gshadow"
 #define	_PATH_KMEM	"/dev/kmem"
-#define	_PATH_LASTLOG	"/var/log/lastlog"
+#define _PATH_LASTLOG_VER ".v2"
+#define	_PATH_LASTLOG	"/var/log/lastlog" _PATH_LASTLOG_VER
 #define	_PATH_MAILDIR	"/var/mail"
 #define	_PATH_MAN	"/usr/share/man"
 #define	_PATH_MEM	"/dev/mem"
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 3a657d5e0d..d5e44b181b 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2215,6 +2215,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 4f91e85ba0..1516f80402 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2183,6 +2183,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 764ea51779..5ac4b37c02 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2265,6 +2265,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index 2ebd24f3a6..cefb1394e8 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -1943,6 +1943,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 5cfcb00ddb..8111b49085 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -167,6 +167,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index d140654389..4dba1f2f46 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -164,6 +164,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 11aa688b83..a5ff3d90ca 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2127,6 +2127,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 14eef860ac..89a0f11166 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2086,6 +2086,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index e1db1488a9..a7c408d18c 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2253,6 +2253,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index f5b4433142..259b8020e8 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2118,6 +2118,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 213853a1f1..e1171a34aa 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -168,6 +168,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 15dda47ba8..a521506506 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2198,6 +2198,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 3ffd49cbfb..aba642460c 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2178,6 +2178,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 2bccbe960a..d3d653d144 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2175,6 +2175,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 209f5f588b..a4ce56c34f 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2169,6 +2169,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 45d976790c..51fbf0b1e1 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2167,6 +2167,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index ab3156c917..5642781479 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2175,6 +2175,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index f8d0534156..10954ebee4 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2169,6 +2169,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index f56e5ad002..848cb2e599 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2216,6 +2216,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/paths.h b/sysdeps/unix/sysv/linux/paths.h
index 89686bcf88..b78dff7ae3 100644
--- a/sysdeps/unix/sysv/linux/paths.h
+++ b/sysdeps/unix/sysv/linux/paths.h
@@ -47,7 +47,8 @@
 #define	_PATH_GSHADOW	"/etc/gshadow"
 #define	_PATH_KLOG	"/proc/kmsg"
 #define	_PATH_KMEM	"/dev/kmem"
-#define	_PATH_LASTLOG	"/var/log/lastlog"
+#define _PATH_LASTLOG_VER ".v2"
+#define	_PATH_LASTLOG	"/var/log/lastlog" _PATH_LASTLOG_VER
 #define	_PATH_MAILDIR	"/var/mail"
 #define	_PATH_MAN	"/usr/share/man"
 #define	_PATH_MEM	"/dev/mem"
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index cfb457400c..93e83fa602 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2225,6 +2225,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index e1fd74fbad..ec0b6d69b1 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2258,6 +2258,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index 5c9cdb33b4..f5bd1db3a0 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2088,6 +2088,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 4dcac4c766..27863e57af 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2378,6 +2378,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index 69bc04c36c..08c5a32d5d 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -1945,6 +1945,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index dc4a3223e6..88b6fa7fc9 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2145,6 +2145,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/s390/lastlog-compat.h b/sysdeps/unix/sysv/linux/s390/lastlog-compat.h
new file mode 100644
index 0000000000..56fadc3b3b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/lastlog-compat.h
@@ -0,0 +1,38 @@
+/* Compat lastlog definitions.  s390 definition.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _LASTLOG_COMPAT_H
+#define _LASTLOG_COMPAT_H 1
+
+/* The s390 changes its lastlog to 64-bit on glibc 2.9 without any handling
+   of old format.  The is_path_lastlog_compat assumes 64-bit as default.  */
+
+struct lastlog_compat
+{
+  int64_t ll_time;
+  char ll_line[UT_LINESIZE];
+  char ll_host[UT_HOSTSIZE];
+};
+
+static inline bool
+is_path_lastlog_compat (const char *file)
+{
+  return false;
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index cead75acc5..7bc5c8866b 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2212,6 +2212,8 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 31366dd7e6..e26a24fe65 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2113,6 +2113,8 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 6deb52d706..06143b0283 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2093,6 +2093,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index 17a141d5b9..eab2af349b 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2090,6 +2090,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index b64b351797..4783a8fa97 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2214,6 +2214,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index e3e01c29fc..47ded40426 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2141,6 +2141,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 9995da84a8..0d144a0c10 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2100,6 +2100,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index adccf45120..a3580872d3 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2197,6 +2197,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [glibc/azanella/y2038] login: Use 64-bit time on struct lastlog
@ 2021-03-04 11:29 Adhemerval Zanella
  0 siblings, 0 replies; 8+ messages in thread
From: Adhemerval Zanella @ 2021-03-04 11:29 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=a31910301cf6fdbb85d6eb07ad27d31bbef701f8

commit a31910301cf6fdbb85d6eb07ad27d31bbef701f8
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Tue Aug 4 10:50:02 2020 -0300

    login: Use 64-bit time on struct lastlog
    
    The new struct has the same size on both 32-bit and 64-bit
    architectures.  As for utmp{x} 64-bit time_t support, a new file name
    is defined for _PATH_LASTLOG.
    
    Also two new symbols are added that read/write 'struct lastlog'
    entries, 'lastlog_read' and 'lastlog_write'.  Both are GNU extensions
    and handle the 32-bit entry operation if the argument is the old
    _PATH_LASTLOG path.
    
    Different than utmp{x}, no concurrent access is done (such as
    advisory locking).  I modeled these function on how program that
    access lastlog file uses (such as shadow-utils and util-linux).
    
    The s390 is the only architecture that already defined the
    'struct lastlog' with 64-bit time_t and to handle s390 has a specific
    lastlog-compat.h header where 'is_path_lastlog_compat' already
    return false (thus making both lastlog_read and lastlog_write
    always read/write registers with 64-bit ll_time).
    
    It also fixes BZ#25844 by adding the __attribute_nonstring__ on
    ll_line and ll_host.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.

Diff:
---
 bits/types/struct_lastlog.h                        | 10 +--
 login/Makefile                                     |  5 +-
 login/Versions                                     |  2 +
 .../struct_lastlog.h => login/lastlog-compat.h     | 27 ++++----
 login/lastlog_read.c                               | 71 +++++++++++++++++++
 login/lastlog_write.c                              | 59 ++++++++++++++++
 login/tst-lastlog.c                                | 79 ++++++++++++++++++++++
 login/tst-lastlog.root/tst-lastlog.script          |  6 ++
 login/utmp.h                                       | 11 +++
 sysdeps/generic/paths.h                            |  3 +-
 sysdeps/mach/hurd/i386/libc.abilist                |  2 +
 sysdeps/unix/sysv/linux/aarch64/libc.abilist       |  2 +
 sysdeps/unix/sysv/linux/alpha/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/arc/libc.abilist           |  2 +
 sysdeps/unix/sysv/linux/arm/be/libc.abilist        |  2 +
 sysdeps/unix/sysv/linux/arm/le/libc.abilist        |  2 +
 sysdeps/unix/sysv/linux/csky/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/hppa/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/i386/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/ia64/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/microblaze/be/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/microblaze/le/libc.abilist |  2 +
 .../unix/sysv/linux/mips/mips32/fpu/libc.abilist   |  2 +
 .../unix/sysv/linux/mips/mips32/nofpu/libc.abilist |  2 +
 .../unix/sysv/linux/mips/mips64/n32/libc.abilist   |  2 +
 .../unix/sysv/linux/mips/mips64/n64/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/nios2/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/paths.h                    |  3 +-
 .../sysv/linux/powerpc/powerpc32/fpu/libc.abilist  |  2 +
 .../linux/powerpc/powerpc32/nofpu/libc.abilist     |  2 +
 .../sysv/linux/powerpc/powerpc64/be/libc.abilist   |  2 +
 .../sysv/linux/powerpc/powerpc64/le/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist    |  2 +
 sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist    |  2 +
 sysdeps/unix/sysv/linux/s390/lastlog-compat.h      | 38 +++++++++++
 sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist  |  2 +
 sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist  |  2 +
 sysdeps/unix/sysv/linux/sh/be/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/sh/le/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/x86_64/64/libc.abilist     |  2 +
 sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist    |  2 +
 45 files changed, 357 insertions(+), 23 deletions(-)

diff --git a/bits/types/struct_lastlog.h b/bits/types/struct_lastlog.h
index 67ffec1b08..8c87958bec 100644
--- a/bits/types/struct_lastlog.h
+++ b/bits/types/struct_lastlog.h
@@ -24,11 +24,7 @@
    previous logins.  */
 struct lastlog
 {
-#if __WORDSIZE_TIME64_COMPAT32
-  int32_t ll_time;
-#else
-  __time_t ll_time;
-#endif
-  char ll_line[UT_LINESIZE];
-  char ll_host[UT_HOSTSIZE];
+  int64_t ll_time;
+  char ll_line[UT_LINESIZE] __attribute_nonstring__;
+  char ll_host[UT_HOSTSIZE] __attribute_nonstring__;
 };
diff --git a/login/Makefile b/login/Makefile
index b5569683fa..4b5a3f0d63 100644
--- a/login/Makefile
+++ b/login/Makefile
@@ -31,7 +31,8 @@ headers	:= utmp.h bits/utmp.h lastlog.h pty.h \
 routines := getlogin getlogin_r setlogin getlogin_r_chk \
 	    getutent getutent_r getutid getutline getutid_r getutline_r \
 	    utmp_file utmpname updwtmp getpt grantpt unlockpt ptsname \
-	    ptsname_r_chk utmp32 utmpx32 utmp-convert
+	    ptsname_r_chk utmp32 utmpx32 utmp-convert \
+	    lastlog_read lastlog_write
 
 CFLAGS-grantpt.c += -DLIBEXECDIR='"$(libexecdir)"'
 
@@ -50,7 +51,7 @@ tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \
   tst-pututxline-lockfail tst-pututxline-cache
 
 tests-container-internal := tst-utmp32
-tests-container := tst-utmp-default
+tests-container := tst-utmp-default tst-lastlog
 
 # Build the -lutil library with these extra functions.
 extra-libs      := libutil
diff --git a/login/Versions b/login/Versions
index d28ecdca9f..5751fdcb71 100644
--- a/login/Versions
+++ b/login/Versions
@@ -57,6 +57,8 @@ libc {
     getutxent;
     getutxid;
     getutxline;
+    lastlog_read;
+    lastlog_write;
     pututline;
     pututxline;
     updwtmp;
diff --git a/sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h b/login/lastlog-compat.h
similarity index 74%
rename from sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h
rename to login/lastlog-compat.h
index 1faa472ec8..687774a21e 100644
--- a/sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h
+++ b/login/lastlog-compat.h
@@ -1,4 +1,4 @@
-/* The 'struct lastlog' type.
+/* Compat lastlog definitions.
    Copyright (C) 2020 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,19 +16,22 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#ifndef _UTMP_H
-# error "Never include <bits/struct_lastlog.h> directly; use <utmp.h> instead."
-#endif
+#ifndef _LASTLOG_COMPAT_H
+#define _LASTLOG_COMPAT_H 1
+
+#include <string.h>
 
-/* The structure describing an entry in the database of
-   previous logins.  */
-struct lastlog
+struct lastlog_compat
 {
-#if __WORDSIZE == 32
-  int64_t ll_time;
-#else
-  __time_t ll_time;
-#endif
+  int32_t ll_time;
   char ll_line[UT_LINESIZE];
   char ll_host[UT_HOSTSIZE];
 };
+
+static inline bool
+is_path_lastlog_compat (const char *file)
+{
+  return strcmp (file, "/var/log/lastlog") == 0;
+}
+
+#endif
diff --git a/login/lastlog_read.c b/login/lastlog_read.c
new file mode 100644
index 0000000000..e2c6e82a15
--- /dev/null
+++ b/login/lastlog_read.c
@@ -0,0 +1,71 @@
+/* Read a lastlog entry.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <utmp.h>
+#include <stdbool.h>
+#include <not-cancel.h>
+#include <lastlog-compat.h>
+
+ssize_t
+lastlog_read (const char *file, uid_t uid, struct lastlog *ll)
+{
+  int fd = __open_nocancel (file, O_RDONLY | O_LARGEFILE | O_CLOEXEC);
+  if (fd == -1)
+    return -1;
+
+  size_t llsize;
+  struct lastlog_compat llcompat;
+  void *data;
+
+  if (is_path_lastlog_compat (file))
+    {
+      llsize = sizeof (struct lastlog_compat);
+      data = &llcompat;
+    }
+  else
+    {
+      llsize = sizeof (struct lastlog);
+      data = ll;
+    }
+
+  off64_t off = llsize * uid;
+  ssize_t r = __pread64_nocancel (fd, data, llsize, off);
+  __close_nocancel_nostatus (fd);
+
+  if (r == llsize && data == &llcompat)
+    {
+      ll->ll_time = llcompat.ll_time;
+      memcpy (ll->ll_line, llcompat.ll_line, UT_LINESIZE);
+      memcpy (ll->ll_host, llcompat.ll_host, UT_HOSTSIZE);
+    }
+
+  if (r == llsize)
+    {
+      if (data == &llcompat)
+	{
+	  ll->ll_time = llcompat.ll_time;
+	  memcpy (ll->ll_line, llcompat.ll_line, UT_LINESIZE);
+	  memcpy (ll->ll_host, llcompat.ll_host, UT_HOSTSIZE);
+	}
+      /* We need to return the expected 'struct lastlog' size in case of
+	 success.  */
+      r = sizeof (struct lastlog);
+    }
+
+  return r;
+}
diff --git a/login/lastlog_write.c b/login/lastlog_write.c
new file mode 100644
index 0000000000..f3aedcbdb7
--- /dev/null
+++ b/login/lastlog_write.c
@@ -0,0 +1,59 @@
+/* Write a lastlog entry.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <utmp.h>
+#include <stdbool.h>
+#include <not-cancel.h>
+#include <lastlog-compat.h>
+
+ssize_t
+lastlog_write (const char *file, uid_t uid, const struct lastlog *ll)
+{
+  int fd = __open_nocancel (file, O_WRONLY | O_LARGEFILE | O_CLOEXEC);
+  if (fd == -1)
+    return -1;
+
+  size_t llsize;
+  struct lastlog_compat llcompat;
+  const void *data;
+
+  if (is_path_lastlog_compat (file))
+    {
+      llcompat.ll_time = ll->ll_time;
+      memcpy (llcompat.ll_line, ll->ll_line, UT_LINESIZE);
+      memcpy (llcompat.ll_host, ll->ll_host, UT_HOSTSIZE);
+      llsize = sizeof (struct lastlog_compat);
+      data = &llcompat;
+    }
+  else
+    {
+      llsize = sizeof (struct lastlog);
+      data = ll;
+    }
+
+  off64_t off = llsize * uid;
+  ssize_t r = __pwrite64_nocancel (fd, data, llsize, off);
+  __close_nocancel_nostatus (fd);
+
+  /* We need to return the expected 'struct lastlog' size in case of
+     success.  */
+  if (r == llsize && data == &llcompat)
+    r = sizeof (struct lastlog);
+
+  return r;
+}
diff --git a/login/tst-lastlog.c b/login/tst-lastlog.c
new file mode 100644
index 0000000000..9376a6ddf4
--- /dev/null
+++ b/login/tst-lastlog.c
@@ -0,0 +1,79 @@
+/* Tests for lastlog read/write functions.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+#include <string.h>
+#include <utmp.h>
+
+#include <support/check.h>
+#include <support/temp_file.h>
+
+#include <stdio.h>
+
+static struct
+{
+  uid_t uid;
+  struct lastlog ll;
+} entry[] =
+{
+  { 0,    { .ll_time = 1000, .ll_line = "tty1" } },
+  { 1000, { .ll_time = 2000, .ll_line = "pts/0", .ll_host = "127.0.0.1" } },
+  { 20,   { .ll_time = 3000, .ll_line = "pts/1", .ll_host = "192.168.0.1" } },
+  { 30,   { .ll_time = 4000, .ll_line = "tty2" } },
+};
+const size_t entry_size = sizeof (entry) / sizeof (entry[0]);
+
+static void
+run_test (const char *filename)
+{
+  for (int n = 0; n < entry_size; n++)
+    TEST_COMPARE (lastlog_write (filename, entry[n].uid, &entry[n].ll),
+		  sizeof (struct lastlog));
+
+  for (int n = 0; n < entry_size; n++)
+    {
+      struct lastlog ll;
+      TEST_COMPARE (lastlog_read (filename, entry[n].uid, &ll),
+		    sizeof (struct lastlog));
+      TEST_COMPARE (ll.ll_time, entry[n].ll.ll_time);
+      TEST_COMPARE_BLOB (ll.ll_line, UT_LINESIZE,
+			 entry[n].ll.ll_line, UT_LINESIZE);
+      TEST_COMPARE_BLOB (ll.ll_host, UT_HOSTSIZE,
+			 entry[n].ll.ll_host, UT_HOSTSIZE);
+    }
+
+  /* Check with an non present uid.  */
+  {
+    struct lastlog ll;
+    TEST_COMPARE (lastlog_read (filename, 4000, &ll), 0);
+  }
+}
+
+static int
+do_test (void)
+{
+  /* The path triggers the read/write of compat (32-bit ll_time) entries.  */
+  run_test ("/var/run/lastlog");
+
+  /* Any other file handles new (64-bit ll_time) entries.  */
+  run_test ("/var/run/lastlog.v2");
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/login/tst-lastlog.root/tst-lastlog.script b/login/tst-lastlog.root/tst-lastlog.script
new file mode 100644
index 0000000000..ca34ce7021
--- /dev/null
+++ b/login/tst-lastlog.root/tst-lastlog.script
@@ -0,0 +1,6 @@
+mkdirp 0755 /var/run
+touch  0664 /var/run/lastlog
+touch  0664 /var/run/lastlog.v2
+
+# Must run localedef as root to write into default paths.
+su
diff --git a/login/utmp.h b/login/utmp.h
index 7fc2d5cdf1..02a445ee82 100644
--- a/login/utmp.h
+++ b/login/utmp.h
@@ -91,6 +91,17 @@ extern int getutline_r (const struct utmp *__line,
 
 #endif	/* Use misc.  */
 
+#ifdef __USE_GNU
+/* Read the struct lastlog LL with UID from file FILE.  */
+extern ssize_t lastlog_read (const char *__file, uid_t __uid,
+			     struct lastlog *__ll)
+     __THROW __nonnull ((1, 3));
+/* Write the struct lastlog LL with UID from file FILE.  */
+extern ssize_t lastlog_write (const char *__file, uid_t __uid,
+			      const struct lastlog *__ll)
+     __THROW __nonnull ((1, 3));
+#endif
+
 __END_DECLS
 
 #endif /* utmp.h  */
diff --git a/sysdeps/generic/paths.h b/sysdeps/generic/paths.h
index ab2980e14a..9321ad7294 100644
--- a/sysdeps/generic/paths.h
+++ b/sysdeps/generic/paths.h
@@ -46,7 +46,8 @@
 #define	_PATH_DRUM	"/dev/drum"
 #define	_PATH_GSHADOW	"/etc/gshadow"
 #define	_PATH_KMEM	"/dev/kmem"
-#define	_PATH_LASTLOG	"/var/log/lastlog"
+#define _PATH_LASTLOG_VER ".v2"
+#define	_PATH_LASTLOG	"/var/log/lastlog" _PATH_LASTLOG_VER
 #define	_PATH_MAILDIR	"/var/mail"
 #define	_PATH_MAN	"/usr/share/man"
 #define	_PATH_MEM	"/dev/mem"
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 3a657d5e0d..d5e44b181b 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2215,6 +2215,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 4f91e85ba0..1516f80402 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2183,6 +2183,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 764ea51779..5ac4b37c02 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2265,6 +2265,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index 2ebd24f3a6..cefb1394e8 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -1943,6 +1943,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 5cfcb00ddb..8111b49085 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -167,6 +167,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index d140654389..4dba1f2f46 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -164,6 +164,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 11aa688b83..a5ff3d90ca 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2127,6 +2127,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 14eef860ac..89a0f11166 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2086,6 +2086,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index e1db1488a9..a7c408d18c 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2253,6 +2253,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index f5b4433142..259b8020e8 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2118,6 +2118,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 213853a1f1..e1171a34aa 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -168,6 +168,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 15dda47ba8..a521506506 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2198,6 +2198,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 3ffd49cbfb..aba642460c 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2178,6 +2178,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 2bccbe960a..d3d653d144 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2175,6 +2175,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 209f5f588b..a4ce56c34f 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2169,6 +2169,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 45d976790c..51fbf0b1e1 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2167,6 +2167,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index ab3156c917..5642781479 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2175,6 +2175,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index f8d0534156..10954ebee4 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2169,6 +2169,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index f56e5ad002..848cb2e599 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2216,6 +2216,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/paths.h b/sysdeps/unix/sysv/linux/paths.h
index 89686bcf88..b78dff7ae3 100644
--- a/sysdeps/unix/sysv/linux/paths.h
+++ b/sysdeps/unix/sysv/linux/paths.h
@@ -47,7 +47,8 @@
 #define	_PATH_GSHADOW	"/etc/gshadow"
 #define	_PATH_KLOG	"/proc/kmsg"
 #define	_PATH_KMEM	"/dev/kmem"
-#define	_PATH_LASTLOG	"/var/log/lastlog"
+#define _PATH_LASTLOG_VER ".v2"
+#define	_PATH_LASTLOG	"/var/log/lastlog" _PATH_LASTLOG_VER
 #define	_PATH_MAILDIR	"/var/mail"
 #define	_PATH_MAN	"/usr/share/man"
 #define	_PATH_MEM	"/dev/mem"
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index cfb457400c..93e83fa602 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2225,6 +2225,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index e1fd74fbad..ec0b6d69b1 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2258,6 +2258,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index 5c9cdb33b4..f5bd1db3a0 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2088,6 +2088,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 4dcac4c766..27863e57af 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2378,6 +2378,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index 69bc04c36c..08c5a32d5d 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -1945,6 +1945,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index dc4a3223e6..88b6fa7fc9 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2145,6 +2145,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/s390/lastlog-compat.h b/sysdeps/unix/sysv/linux/s390/lastlog-compat.h
new file mode 100644
index 0000000000..56fadc3b3b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/lastlog-compat.h
@@ -0,0 +1,38 @@
+/* Compat lastlog definitions.  s390 definition.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _LASTLOG_COMPAT_H
+#define _LASTLOG_COMPAT_H 1
+
+/* The s390 changes its lastlog to 64-bit on glibc 2.9 without any handling
+   of old format.  The is_path_lastlog_compat assumes 64-bit as default.  */
+
+struct lastlog_compat
+{
+  int64_t ll_time;
+  char ll_line[UT_LINESIZE];
+  char ll_host[UT_HOSTSIZE];
+};
+
+static inline bool
+is_path_lastlog_compat (const char *file)
+{
+  return false;
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index cead75acc5..7bc5c8866b 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2212,6 +2212,8 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 31366dd7e6..e26a24fe65 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2113,6 +2113,8 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 6deb52d706..06143b0283 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2093,6 +2093,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index 17a141d5b9..eab2af349b 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2090,6 +2090,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index b64b351797..4783a8fa97 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2214,6 +2214,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index e3e01c29fc..47ded40426 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2141,6 +2141,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 9995da84a8..0d144a0c10 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2100,6 +2100,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index adccf45120..a3580872d3 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2197,6 +2197,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [glibc/azanella/y2038] login: Use 64-bit time on struct lastlog
@ 2021-03-02 12:31 Adhemerval Zanella
  0 siblings, 0 replies; 8+ messages in thread
From: Adhemerval Zanella @ 2021-03-02 12:31 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=4b882ddf57d227aa3c4fe7b7fc3e79a02b0cd805

commit 4b882ddf57d227aa3c4fe7b7fc3e79a02b0cd805
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Tue Aug 4 10:50:02 2020 -0300

    login: Use 64-bit time on struct lastlog
    
    The new struct has the same size on both 32-bit and 64-bit
    architectures.  As for utmp{x} 64-bit time_t support, a new file name
    is defined for _PATH_LASTLOG.
    
    Also two new symbols are added that read/write 'struct lastlog'
    entries, 'lastlog_read' and 'lastlog_write'.  Both are GNU extensions
    and handle the 32-bit entry operation if the argument is the old
    _PATH_LASTLOG path.
    
    Different than utmp{x}, no concurrent access is done (such as
    advisory locking).  I modeled these function on how program that
    access lastlog file uses (such as shadow-utils and util-linux).
    
    The s390 is the only architecture that already defined the
    'struct lastlog' with 64-bit time_t and to handle s390 has a specific
    lastlog-compat.h header where 'is_path_lastlog_compat' already
    return false (thus making both lastlog_read and lastlog_write
    always read/write registers with 64-bit ll_time).
    
    It also fixes BZ#25844 by adding the __attribute_nonstring__ on
    ll_line and ll_host.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.

Diff:
---
 bits/types/struct_lastlog.h                        | 10 +--
 login/Makefile                                     |  5 +-
 login/Versions                                     |  2 +
 .../struct_lastlog.h => login/lastlog-compat.h     | 27 ++++----
 login/lastlog_read.c                               | 71 +++++++++++++++++++
 login/lastlog_write.c                              | 59 ++++++++++++++++
 login/tst-lastlog.c                                | 79 ++++++++++++++++++++++
 login/tst-lastlog.root/tst-lastlog.script          |  6 ++
 login/utmp.h                                       | 11 +++
 sysdeps/generic/paths.h                            |  3 +-
 sysdeps/mach/hurd/i386/libc.abilist                |  2 +
 sysdeps/unix/sysv/linux/aarch64/libc.abilist       |  2 +
 sysdeps/unix/sysv/linux/alpha/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/arc/libc.abilist           |  2 +
 sysdeps/unix/sysv/linux/arm/be/libc.abilist        |  2 +
 sysdeps/unix/sysv/linux/arm/le/libc.abilist        |  2 +
 sysdeps/unix/sysv/linux/csky/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/hppa/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/i386/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/ia64/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/microblaze/be/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/microblaze/le/libc.abilist |  2 +
 .../unix/sysv/linux/mips/mips32/fpu/libc.abilist   |  2 +
 .../unix/sysv/linux/mips/mips32/nofpu/libc.abilist |  2 +
 .../unix/sysv/linux/mips/mips64/n32/libc.abilist   |  2 +
 .../unix/sysv/linux/mips/mips64/n64/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/nios2/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/paths.h                    |  3 +-
 .../sysv/linux/powerpc/powerpc32/fpu/libc.abilist  |  2 +
 .../linux/powerpc/powerpc32/nofpu/libc.abilist     |  2 +
 .../sysv/linux/powerpc/powerpc64/be/libc.abilist   |  2 +
 .../sysv/linux/powerpc/powerpc64/le/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist    |  2 +
 sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist    |  2 +
 sysdeps/unix/sysv/linux/s390/lastlog-compat.h      | 38 +++++++++++
 sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist  |  2 +
 sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist  |  2 +
 sysdeps/unix/sysv/linux/sh/be/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/sh/le/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/x86_64/64/libc.abilist     |  2 +
 sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist    |  2 +
 45 files changed, 357 insertions(+), 23 deletions(-)

diff --git a/bits/types/struct_lastlog.h b/bits/types/struct_lastlog.h
index 67ffec1b08..8c87958bec 100644
--- a/bits/types/struct_lastlog.h
+++ b/bits/types/struct_lastlog.h
@@ -24,11 +24,7 @@
    previous logins.  */
 struct lastlog
 {
-#if __WORDSIZE_TIME64_COMPAT32
-  int32_t ll_time;
-#else
-  __time_t ll_time;
-#endif
-  char ll_line[UT_LINESIZE];
-  char ll_host[UT_HOSTSIZE];
+  int64_t ll_time;
+  char ll_line[UT_LINESIZE] __attribute_nonstring__;
+  char ll_host[UT_HOSTSIZE] __attribute_nonstring__;
 };
diff --git a/login/Makefile b/login/Makefile
index b5569683fa..4b5a3f0d63 100644
--- a/login/Makefile
+++ b/login/Makefile
@@ -31,7 +31,8 @@ headers	:= utmp.h bits/utmp.h lastlog.h pty.h \
 routines := getlogin getlogin_r setlogin getlogin_r_chk \
 	    getutent getutent_r getutid getutline getutid_r getutline_r \
 	    utmp_file utmpname updwtmp getpt grantpt unlockpt ptsname \
-	    ptsname_r_chk utmp32 utmpx32 utmp-convert
+	    ptsname_r_chk utmp32 utmpx32 utmp-convert \
+	    lastlog_read lastlog_write
 
 CFLAGS-grantpt.c += -DLIBEXECDIR='"$(libexecdir)"'
 
@@ -50,7 +51,7 @@ tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \
   tst-pututxline-lockfail tst-pututxline-cache
 
 tests-container-internal := tst-utmp32
-tests-container := tst-utmp-default
+tests-container := tst-utmp-default tst-lastlog
 
 # Build the -lutil library with these extra functions.
 extra-libs      := libutil
diff --git a/login/Versions b/login/Versions
index d28ecdca9f..5751fdcb71 100644
--- a/login/Versions
+++ b/login/Versions
@@ -57,6 +57,8 @@ libc {
     getutxent;
     getutxid;
     getutxline;
+    lastlog_read;
+    lastlog_write;
     pututline;
     pututxline;
     updwtmp;
diff --git a/sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h b/login/lastlog-compat.h
similarity index 74%
rename from sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h
rename to login/lastlog-compat.h
index 1faa472ec8..687774a21e 100644
--- a/sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h
+++ b/login/lastlog-compat.h
@@ -1,4 +1,4 @@
-/* The 'struct lastlog' type.
+/* Compat lastlog definitions.
    Copyright (C) 2020 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,19 +16,22 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#ifndef _UTMP_H
-# error "Never include <bits/struct_lastlog.h> directly; use <utmp.h> instead."
-#endif
+#ifndef _LASTLOG_COMPAT_H
+#define _LASTLOG_COMPAT_H 1
+
+#include <string.h>
 
-/* The structure describing an entry in the database of
-   previous logins.  */
-struct lastlog
+struct lastlog_compat
 {
-#if __WORDSIZE == 32
-  int64_t ll_time;
-#else
-  __time_t ll_time;
-#endif
+  int32_t ll_time;
   char ll_line[UT_LINESIZE];
   char ll_host[UT_HOSTSIZE];
 };
+
+static inline bool
+is_path_lastlog_compat (const char *file)
+{
+  return strcmp (file, "/var/log/lastlog") == 0;
+}
+
+#endif
diff --git a/login/lastlog_read.c b/login/lastlog_read.c
new file mode 100644
index 0000000000..e2c6e82a15
--- /dev/null
+++ b/login/lastlog_read.c
@@ -0,0 +1,71 @@
+/* Read a lastlog entry.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <utmp.h>
+#include <stdbool.h>
+#include <not-cancel.h>
+#include <lastlog-compat.h>
+
+ssize_t
+lastlog_read (const char *file, uid_t uid, struct lastlog *ll)
+{
+  int fd = __open_nocancel (file, O_RDONLY | O_LARGEFILE | O_CLOEXEC);
+  if (fd == -1)
+    return -1;
+
+  size_t llsize;
+  struct lastlog_compat llcompat;
+  void *data;
+
+  if (is_path_lastlog_compat (file))
+    {
+      llsize = sizeof (struct lastlog_compat);
+      data = &llcompat;
+    }
+  else
+    {
+      llsize = sizeof (struct lastlog);
+      data = ll;
+    }
+
+  off64_t off = llsize * uid;
+  ssize_t r = __pread64_nocancel (fd, data, llsize, off);
+  __close_nocancel_nostatus (fd);
+
+  if (r == llsize && data == &llcompat)
+    {
+      ll->ll_time = llcompat.ll_time;
+      memcpy (ll->ll_line, llcompat.ll_line, UT_LINESIZE);
+      memcpy (ll->ll_host, llcompat.ll_host, UT_HOSTSIZE);
+    }
+
+  if (r == llsize)
+    {
+      if (data == &llcompat)
+	{
+	  ll->ll_time = llcompat.ll_time;
+	  memcpy (ll->ll_line, llcompat.ll_line, UT_LINESIZE);
+	  memcpy (ll->ll_host, llcompat.ll_host, UT_HOSTSIZE);
+	}
+      /* We need to return the expected 'struct lastlog' size in case of
+	 success.  */
+      r = sizeof (struct lastlog);
+    }
+
+  return r;
+}
diff --git a/login/lastlog_write.c b/login/lastlog_write.c
new file mode 100644
index 0000000000..f3aedcbdb7
--- /dev/null
+++ b/login/lastlog_write.c
@@ -0,0 +1,59 @@
+/* Write a lastlog entry.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <utmp.h>
+#include <stdbool.h>
+#include <not-cancel.h>
+#include <lastlog-compat.h>
+
+ssize_t
+lastlog_write (const char *file, uid_t uid, const struct lastlog *ll)
+{
+  int fd = __open_nocancel (file, O_WRONLY | O_LARGEFILE | O_CLOEXEC);
+  if (fd == -1)
+    return -1;
+
+  size_t llsize;
+  struct lastlog_compat llcompat;
+  const void *data;
+
+  if (is_path_lastlog_compat (file))
+    {
+      llcompat.ll_time = ll->ll_time;
+      memcpy (llcompat.ll_line, ll->ll_line, UT_LINESIZE);
+      memcpy (llcompat.ll_host, ll->ll_host, UT_HOSTSIZE);
+      llsize = sizeof (struct lastlog_compat);
+      data = &llcompat;
+    }
+  else
+    {
+      llsize = sizeof (struct lastlog);
+      data = ll;
+    }
+
+  off64_t off = llsize * uid;
+  ssize_t r = __pwrite64_nocancel (fd, data, llsize, off);
+  __close_nocancel_nostatus (fd);
+
+  /* We need to return the expected 'struct lastlog' size in case of
+     success.  */
+  if (r == llsize && data == &llcompat)
+    r = sizeof (struct lastlog);
+
+  return r;
+}
diff --git a/login/tst-lastlog.c b/login/tst-lastlog.c
new file mode 100644
index 0000000000..9376a6ddf4
--- /dev/null
+++ b/login/tst-lastlog.c
@@ -0,0 +1,79 @@
+/* Tests for lastlog read/write functions.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+#include <string.h>
+#include <utmp.h>
+
+#include <support/check.h>
+#include <support/temp_file.h>
+
+#include <stdio.h>
+
+static struct
+{
+  uid_t uid;
+  struct lastlog ll;
+} entry[] =
+{
+  { 0,    { .ll_time = 1000, .ll_line = "tty1" } },
+  { 1000, { .ll_time = 2000, .ll_line = "pts/0", .ll_host = "127.0.0.1" } },
+  { 20,   { .ll_time = 3000, .ll_line = "pts/1", .ll_host = "192.168.0.1" } },
+  { 30,   { .ll_time = 4000, .ll_line = "tty2" } },
+};
+const size_t entry_size = sizeof (entry) / sizeof (entry[0]);
+
+static void
+run_test (const char *filename)
+{
+  for (int n = 0; n < entry_size; n++)
+    TEST_COMPARE (lastlog_write (filename, entry[n].uid, &entry[n].ll),
+		  sizeof (struct lastlog));
+
+  for (int n = 0; n < entry_size; n++)
+    {
+      struct lastlog ll;
+      TEST_COMPARE (lastlog_read (filename, entry[n].uid, &ll),
+		    sizeof (struct lastlog));
+      TEST_COMPARE (ll.ll_time, entry[n].ll.ll_time);
+      TEST_COMPARE_BLOB (ll.ll_line, UT_LINESIZE,
+			 entry[n].ll.ll_line, UT_LINESIZE);
+      TEST_COMPARE_BLOB (ll.ll_host, UT_HOSTSIZE,
+			 entry[n].ll.ll_host, UT_HOSTSIZE);
+    }
+
+  /* Check with an non present uid.  */
+  {
+    struct lastlog ll;
+    TEST_COMPARE (lastlog_read (filename, 4000, &ll), 0);
+  }
+}
+
+static int
+do_test (void)
+{
+  /* The path triggers the read/write of compat (32-bit ll_time) entries.  */
+  run_test ("/var/run/lastlog");
+
+  /* Any other file handles new (64-bit ll_time) entries.  */
+  run_test ("/var/run/lastlog.v2");
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/login/tst-lastlog.root/tst-lastlog.script b/login/tst-lastlog.root/tst-lastlog.script
new file mode 100644
index 0000000000..ca34ce7021
--- /dev/null
+++ b/login/tst-lastlog.root/tst-lastlog.script
@@ -0,0 +1,6 @@
+mkdirp 0755 /var/run
+touch  0664 /var/run/lastlog
+touch  0664 /var/run/lastlog.v2
+
+# Must run localedef as root to write into default paths.
+su
diff --git a/login/utmp.h b/login/utmp.h
index 7fc2d5cdf1..02a445ee82 100644
--- a/login/utmp.h
+++ b/login/utmp.h
@@ -91,6 +91,17 @@ extern int getutline_r (const struct utmp *__line,
 
 #endif	/* Use misc.  */
 
+#ifdef __USE_GNU
+/* Read the struct lastlog LL with UID from file FILE.  */
+extern ssize_t lastlog_read (const char *__file, uid_t __uid,
+			     struct lastlog *__ll)
+     __THROW __nonnull ((1, 3));
+/* Write the struct lastlog LL with UID from file FILE.  */
+extern ssize_t lastlog_write (const char *__file, uid_t __uid,
+			      const struct lastlog *__ll)
+     __THROW __nonnull ((1, 3));
+#endif
+
 __END_DECLS
 
 #endif /* utmp.h  */
diff --git a/sysdeps/generic/paths.h b/sysdeps/generic/paths.h
index ab2980e14a..9321ad7294 100644
--- a/sysdeps/generic/paths.h
+++ b/sysdeps/generic/paths.h
@@ -46,7 +46,8 @@
 #define	_PATH_DRUM	"/dev/drum"
 #define	_PATH_GSHADOW	"/etc/gshadow"
 #define	_PATH_KMEM	"/dev/kmem"
-#define	_PATH_LASTLOG	"/var/log/lastlog"
+#define _PATH_LASTLOG_VER ".v2"
+#define	_PATH_LASTLOG	"/var/log/lastlog" _PATH_LASTLOG_VER
 #define	_PATH_MAILDIR	"/var/mail"
 #define	_PATH_MAN	"/usr/share/man"
 #define	_PATH_MEM	"/dev/mem"
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 3a657d5e0d..d5e44b181b 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2215,6 +2215,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 4f91e85ba0..1516f80402 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2183,6 +2183,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 764ea51779..5ac4b37c02 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2265,6 +2265,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index 2ebd24f3a6..cefb1394e8 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -1943,6 +1943,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 5cfcb00ddb..8111b49085 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -167,6 +167,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index d140654389..4dba1f2f46 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -164,6 +164,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 11aa688b83..a5ff3d90ca 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2127,6 +2127,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 14eef860ac..89a0f11166 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2086,6 +2086,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index e1db1488a9..a7c408d18c 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2253,6 +2253,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index f5b4433142..259b8020e8 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2118,6 +2118,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 213853a1f1..e1171a34aa 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -168,6 +168,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 15dda47ba8..a521506506 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2198,6 +2198,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 3ffd49cbfb..aba642460c 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2178,6 +2178,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 2bccbe960a..d3d653d144 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2175,6 +2175,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 209f5f588b..a4ce56c34f 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2169,6 +2169,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 45d976790c..51fbf0b1e1 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2167,6 +2167,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index ab3156c917..5642781479 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2175,6 +2175,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index f8d0534156..10954ebee4 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2169,6 +2169,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index f56e5ad002..848cb2e599 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2216,6 +2216,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/paths.h b/sysdeps/unix/sysv/linux/paths.h
index 89686bcf88..b78dff7ae3 100644
--- a/sysdeps/unix/sysv/linux/paths.h
+++ b/sysdeps/unix/sysv/linux/paths.h
@@ -47,7 +47,8 @@
 #define	_PATH_GSHADOW	"/etc/gshadow"
 #define	_PATH_KLOG	"/proc/kmsg"
 #define	_PATH_KMEM	"/dev/kmem"
-#define	_PATH_LASTLOG	"/var/log/lastlog"
+#define _PATH_LASTLOG_VER ".v2"
+#define	_PATH_LASTLOG	"/var/log/lastlog" _PATH_LASTLOG_VER
 #define	_PATH_MAILDIR	"/var/mail"
 #define	_PATH_MAN	"/usr/share/man"
 #define	_PATH_MEM	"/dev/mem"
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index cfb457400c..93e83fa602 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2225,6 +2225,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index e1fd74fbad..ec0b6d69b1 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2258,6 +2258,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index 5c9cdb33b4..f5bd1db3a0 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2088,6 +2088,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 4dcac4c766..27863e57af 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2378,6 +2378,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index 69bc04c36c..08c5a32d5d 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -1945,6 +1945,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index dc4a3223e6..88b6fa7fc9 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2145,6 +2145,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/s390/lastlog-compat.h b/sysdeps/unix/sysv/linux/s390/lastlog-compat.h
new file mode 100644
index 0000000000..56fadc3b3b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/lastlog-compat.h
@@ -0,0 +1,38 @@
+/* Compat lastlog definitions.  s390 definition.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _LASTLOG_COMPAT_H
+#define _LASTLOG_COMPAT_H 1
+
+/* The s390 changes its lastlog to 64-bit on glibc 2.9 without any handling
+   of old format.  The is_path_lastlog_compat assumes 64-bit as default.  */
+
+struct lastlog_compat
+{
+  int64_t ll_time;
+  char ll_line[UT_LINESIZE];
+  char ll_host[UT_HOSTSIZE];
+};
+
+static inline bool
+is_path_lastlog_compat (const char *file)
+{
+  return false;
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index cead75acc5..7bc5c8866b 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2212,6 +2212,8 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 31366dd7e6..e26a24fe65 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2113,6 +2113,8 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 6deb52d706..06143b0283 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2093,6 +2093,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index 17a141d5b9..eab2af349b 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2090,6 +2090,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index b64b351797..4783a8fa97 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2214,6 +2214,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index e3e01c29fc..47ded40426 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2141,6 +2141,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 9995da84a8..0d144a0c10 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2100,6 +2100,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index adccf45120..a3580872d3 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2197,6 +2197,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [glibc/azanella/y2038] login: Use 64-bit time on struct lastlog
@ 2021-03-01 17:36 Adhemerval Zanella
  0 siblings, 0 replies; 8+ messages in thread
From: Adhemerval Zanella @ 2021-03-01 17:36 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=803ba548842d1d482e102f6d466e32ddec7ffc48

commit 803ba548842d1d482e102f6d466e32ddec7ffc48
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Tue Aug 4 10:50:02 2020 -0300

    login: Use 64-bit time on struct lastlog
    
    The new struct has the same size on both 32-bit and 64-bit
    architectures.  As for utmp{x} 64-bit time_t support, a new file name
    is defined for _PATH_LASTLOG.
    
    Also two new symbols are added that read/write 'struct lastlog'
    entries, 'lastlog_read' and 'lastlog_write'.  Both are GNU extensions
    and handle the 32-bit entry operation if the argument is the old
    _PATH_LASTLOG path.
    
    Different than utmp{x}, no concurrent access is done (such as
    advisory locking).  I modeled these function on how program that
    access lastlog file uses (such as shadow-utils and util-linux).
    
    The s390 is the only architecture that already defined the
    'struct lastlog' with 64-bit time_t and to handle s390 has a specific
    lastlog-compat.h header where 'is_path_lastlog_compat' already
    return false (thus making both lastlog_read and lastlog_write
    always read/write registers with 64-bit ll_time).
    
    It also fixes BZ#25844 by adding the __attribute_nonstring__ on
    ll_line and ll_host.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.

Diff:
---
 bits/types/struct_lastlog.h                        | 10 +--
 login/Makefile                                     |  5 +-
 login/Versions                                     |  2 +
 .../struct_lastlog.h => login/lastlog-compat.h     | 27 ++++----
 login/lastlog_read.c                               | 71 +++++++++++++++++++
 login/lastlog_write.c                              | 59 ++++++++++++++++
 login/tst-lastlog.c                                | 79 ++++++++++++++++++++++
 login/tst-lastlog.root/tst-lastlog.script          |  6 ++
 login/utmp.h                                       | 11 +++
 sysdeps/generic/paths.h                            |  3 +-
 sysdeps/mach/hurd/i386/libc.abilist                |  2 +
 sysdeps/unix/sysv/linux/aarch64/libc.abilist       |  2 +
 sysdeps/unix/sysv/linux/alpha/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/arc/libc.abilist           |  2 +
 sysdeps/unix/sysv/linux/arm/be/libc.abilist        |  2 +
 sysdeps/unix/sysv/linux/arm/le/libc.abilist        |  2 +
 sysdeps/unix/sysv/linux/csky/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/hppa/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/i386/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/ia64/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/microblaze/be/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/microblaze/le/libc.abilist |  2 +
 .../unix/sysv/linux/mips/mips32/fpu/libc.abilist   |  2 +
 .../unix/sysv/linux/mips/mips32/nofpu/libc.abilist |  2 +
 .../unix/sysv/linux/mips/mips64/n32/libc.abilist   |  2 +
 .../unix/sysv/linux/mips/mips64/n64/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/nios2/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/paths.h                    |  3 +-
 .../sysv/linux/powerpc/powerpc32/fpu/libc.abilist  |  2 +
 .../linux/powerpc/powerpc32/nofpu/libc.abilist     |  2 +
 .../sysv/linux/powerpc/powerpc64/be/libc.abilist   |  2 +
 .../sysv/linux/powerpc/powerpc64/le/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist    |  2 +
 sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist    |  2 +
 sysdeps/unix/sysv/linux/s390/lastlog-compat.h      | 38 +++++++++++
 sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist  |  2 +
 sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist  |  2 +
 sysdeps/unix/sysv/linux/sh/be/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/sh/le/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/x86_64/64/libc.abilist     |  2 +
 sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist    |  2 +
 45 files changed, 357 insertions(+), 23 deletions(-)

diff --git a/bits/types/struct_lastlog.h b/bits/types/struct_lastlog.h
index 67ffec1b08..8c87958bec 100644
--- a/bits/types/struct_lastlog.h
+++ b/bits/types/struct_lastlog.h
@@ -24,11 +24,7 @@
    previous logins.  */
 struct lastlog
 {
-#if __WORDSIZE_TIME64_COMPAT32
-  int32_t ll_time;
-#else
-  __time_t ll_time;
-#endif
-  char ll_line[UT_LINESIZE];
-  char ll_host[UT_HOSTSIZE];
+  int64_t ll_time;
+  char ll_line[UT_LINESIZE] __attribute_nonstring__;
+  char ll_host[UT_HOSTSIZE] __attribute_nonstring__;
 };
diff --git a/login/Makefile b/login/Makefile
index b5569683fa..4b5a3f0d63 100644
--- a/login/Makefile
+++ b/login/Makefile
@@ -31,7 +31,8 @@ headers	:= utmp.h bits/utmp.h lastlog.h pty.h \
 routines := getlogin getlogin_r setlogin getlogin_r_chk \
 	    getutent getutent_r getutid getutline getutid_r getutline_r \
 	    utmp_file utmpname updwtmp getpt grantpt unlockpt ptsname \
-	    ptsname_r_chk utmp32 utmpx32 utmp-convert
+	    ptsname_r_chk utmp32 utmpx32 utmp-convert \
+	    lastlog_read lastlog_write
 
 CFLAGS-grantpt.c += -DLIBEXECDIR='"$(libexecdir)"'
 
@@ -50,7 +51,7 @@ tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \
   tst-pututxline-lockfail tst-pututxline-cache
 
 tests-container-internal := tst-utmp32
-tests-container := tst-utmp-default
+tests-container := tst-utmp-default tst-lastlog
 
 # Build the -lutil library with these extra functions.
 extra-libs      := libutil
diff --git a/login/Versions b/login/Versions
index d28ecdca9f..5751fdcb71 100644
--- a/login/Versions
+++ b/login/Versions
@@ -57,6 +57,8 @@ libc {
     getutxent;
     getutxid;
     getutxline;
+    lastlog_read;
+    lastlog_write;
     pututline;
     pututxline;
     updwtmp;
diff --git a/sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h b/login/lastlog-compat.h
similarity index 74%
rename from sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h
rename to login/lastlog-compat.h
index 1faa472ec8..687774a21e 100644
--- a/sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h
+++ b/login/lastlog-compat.h
@@ -1,4 +1,4 @@
-/* The 'struct lastlog' type.
+/* Compat lastlog definitions.
    Copyright (C) 2020 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,19 +16,22 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#ifndef _UTMP_H
-# error "Never include <bits/struct_lastlog.h> directly; use <utmp.h> instead."
-#endif
+#ifndef _LASTLOG_COMPAT_H
+#define _LASTLOG_COMPAT_H 1
+
+#include <string.h>
 
-/* The structure describing an entry in the database of
-   previous logins.  */
-struct lastlog
+struct lastlog_compat
 {
-#if __WORDSIZE == 32
-  int64_t ll_time;
-#else
-  __time_t ll_time;
-#endif
+  int32_t ll_time;
   char ll_line[UT_LINESIZE];
   char ll_host[UT_HOSTSIZE];
 };
+
+static inline bool
+is_path_lastlog_compat (const char *file)
+{
+  return strcmp (file, "/var/log/lastlog") == 0;
+}
+
+#endif
diff --git a/login/lastlog_read.c b/login/lastlog_read.c
new file mode 100644
index 0000000000..e2c6e82a15
--- /dev/null
+++ b/login/lastlog_read.c
@@ -0,0 +1,71 @@
+/* Read a lastlog entry.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <utmp.h>
+#include <stdbool.h>
+#include <not-cancel.h>
+#include <lastlog-compat.h>
+
+ssize_t
+lastlog_read (const char *file, uid_t uid, struct lastlog *ll)
+{
+  int fd = __open_nocancel (file, O_RDONLY | O_LARGEFILE | O_CLOEXEC);
+  if (fd == -1)
+    return -1;
+
+  size_t llsize;
+  struct lastlog_compat llcompat;
+  void *data;
+
+  if (is_path_lastlog_compat (file))
+    {
+      llsize = sizeof (struct lastlog_compat);
+      data = &llcompat;
+    }
+  else
+    {
+      llsize = sizeof (struct lastlog);
+      data = ll;
+    }
+
+  off64_t off = llsize * uid;
+  ssize_t r = __pread64_nocancel (fd, data, llsize, off);
+  __close_nocancel_nostatus (fd);
+
+  if (r == llsize && data == &llcompat)
+    {
+      ll->ll_time = llcompat.ll_time;
+      memcpy (ll->ll_line, llcompat.ll_line, UT_LINESIZE);
+      memcpy (ll->ll_host, llcompat.ll_host, UT_HOSTSIZE);
+    }
+
+  if (r == llsize)
+    {
+      if (data == &llcompat)
+	{
+	  ll->ll_time = llcompat.ll_time;
+	  memcpy (ll->ll_line, llcompat.ll_line, UT_LINESIZE);
+	  memcpy (ll->ll_host, llcompat.ll_host, UT_HOSTSIZE);
+	}
+      /* We need to return the expected 'struct lastlog' size in case of
+	 success.  */
+      r = sizeof (struct lastlog);
+    }
+
+  return r;
+}
diff --git a/login/lastlog_write.c b/login/lastlog_write.c
new file mode 100644
index 0000000000..f3aedcbdb7
--- /dev/null
+++ b/login/lastlog_write.c
@@ -0,0 +1,59 @@
+/* Write a lastlog entry.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <utmp.h>
+#include <stdbool.h>
+#include <not-cancel.h>
+#include <lastlog-compat.h>
+
+ssize_t
+lastlog_write (const char *file, uid_t uid, const struct lastlog *ll)
+{
+  int fd = __open_nocancel (file, O_WRONLY | O_LARGEFILE | O_CLOEXEC);
+  if (fd == -1)
+    return -1;
+
+  size_t llsize;
+  struct lastlog_compat llcompat;
+  const void *data;
+
+  if (is_path_lastlog_compat (file))
+    {
+      llcompat.ll_time = ll->ll_time;
+      memcpy (llcompat.ll_line, ll->ll_line, UT_LINESIZE);
+      memcpy (llcompat.ll_host, ll->ll_host, UT_HOSTSIZE);
+      llsize = sizeof (struct lastlog_compat);
+      data = &llcompat;
+    }
+  else
+    {
+      llsize = sizeof (struct lastlog);
+      data = ll;
+    }
+
+  off64_t off = llsize * uid;
+  ssize_t r = __pwrite64_nocancel (fd, data, llsize, off);
+  __close_nocancel_nostatus (fd);
+
+  /* We need to return the expected 'struct lastlog' size in case of
+     success.  */
+  if (r == llsize && data == &llcompat)
+    r = sizeof (struct lastlog);
+
+  return r;
+}
diff --git a/login/tst-lastlog.c b/login/tst-lastlog.c
new file mode 100644
index 0000000000..9376a6ddf4
--- /dev/null
+++ b/login/tst-lastlog.c
@@ -0,0 +1,79 @@
+/* Tests for lastlog read/write functions.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+#include <string.h>
+#include <utmp.h>
+
+#include <support/check.h>
+#include <support/temp_file.h>
+
+#include <stdio.h>
+
+static struct
+{
+  uid_t uid;
+  struct lastlog ll;
+} entry[] =
+{
+  { 0,    { .ll_time = 1000, .ll_line = "tty1" } },
+  { 1000, { .ll_time = 2000, .ll_line = "pts/0", .ll_host = "127.0.0.1" } },
+  { 20,   { .ll_time = 3000, .ll_line = "pts/1", .ll_host = "192.168.0.1" } },
+  { 30,   { .ll_time = 4000, .ll_line = "tty2" } },
+};
+const size_t entry_size = sizeof (entry) / sizeof (entry[0]);
+
+static void
+run_test (const char *filename)
+{
+  for (int n = 0; n < entry_size; n++)
+    TEST_COMPARE (lastlog_write (filename, entry[n].uid, &entry[n].ll),
+		  sizeof (struct lastlog));
+
+  for (int n = 0; n < entry_size; n++)
+    {
+      struct lastlog ll;
+      TEST_COMPARE (lastlog_read (filename, entry[n].uid, &ll),
+		    sizeof (struct lastlog));
+      TEST_COMPARE (ll.ll_time, entry[n].ll.ll_time);
+      TEST_COMPARE_BLOB (ll.ll_line, UT_LINESIZE,
+			 entry[n].ll.ll_line, UT_LINESIZE);
+      TEST_COMPARE_BLOB (ll.ll_host, UT_HOSTSIZE,
+			 entry[n].ll.ll_host, UT_HOSTSIZE);
+    }
+
+  /* Check with an non present uid.  */
+  {
+    struct lastlog ll;
+    TEST_COMPARE (lastlog_read (filename, 4000, &ll), 0);
+  }
+}
+
+static int
+do_test (void)
+{
+  /* The path triggers the read/write of compat (32-bit ll_time) entries.  */
+  run_test ("/var/run/lastlog");
+
+  /* Any other file handles new (64-bit ll_time) entries.  */
+  run_test ("/var/run/lastlog.v2");
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/login/tst-lastlog.root/tst-lastlog.script b/login/tst-lastlog.root/tst-lastlog.script
new file mode 100644
index 0000000000..ca34ce7021
--- /dev/null
+++ b/login/tst-lastlog.root/tst-lastlog.script
@@ -0,0 +1,6 @@
+mkdirp 0755 /var/run
+touch  0664 /var/run/lastlog
+touch  0664 /var/run/lastlog.v2
+
+# Must run localedef as root to write into default paths.
+su
diff --git a/login/utmp.h b/login/utmp.h
index 7fc2d5cdf1..02a445ee82 100644
--- a/login/utmp.h
+++ b/login/utmp.h
@@ -91,6 +91,17 @@ extern int getutline_r (const struct utmp *__line,
 
 #endif	/* Use misc.  */
 
+#ifdef __USE_GNU
+/* Read the struct lastlog LL with UID from file FILE.  */
+extern ssize_t lastlog_read (const char *__file, uid_t __uid,
+			     struct lastlog *__ll)
+     __THROW __nonnull ((1, 3));
+/* Write the struct lastlog LL with UID from file FILE.  */
+extern ssize_t lastlog_write (const char *__file, uid_t __uid,
+			      const struct lastlog *__ll)
+     __THROW __nonnull ((1, 3));
+#endif
+
 __END_DECLS
 
 #endif /* utmp.h  */
diff --git a/sysdeps/generic/paths.h b/sysdeps/generic/paths.h
index ab2980e14a..9321ad7294 100644
--- a/sysdeps/generic/paths.h
+++ b/sysdeps/generic/paths.h
@@ -46,7 +46,8 @@
 #define	_PATH_DRUM	"/dev/drum"
 #define	_PATH_GSHADOW	"/etc/gshadow"
 #define	_PATH_KMEM	"/dev/kmem"
-#define	_PATH_LASTLOG	"/var/log/lastlog"
+#define _PATH_LASTLOG_VER ".v2"
+#define	_PATH_LASTLOG	"/var/log/lastlog" _PATH_LASTLOG_VER
 #define	_PATH_MAILDIR	"/var/mail"
 #define	_PATH_MAN	"/usr/share/man"
 #define	_PATH_MEM	"/dev/mem"
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 3a657d5e0d..d5e44b181b 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2215,6 +2215,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 4f91e85ba0..1516f80402 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2183,6 +2183,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 764ea51779..5ac4b37c02 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2265,6 +2265,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index 2ebd24f3a6..cefb1394e8 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -1943,6 +1943,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 5cfcb00ddb..8111b49085 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -167,6 +167,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index d140654389..4dba1f2f46 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -164,6 +164,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 11aa688b83..a5ff3d90ca 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2127,6 +2127,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 14eef860ac..89a0f11166 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2086,6 +2086,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index e1db1488a9..a7c408d18c 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2253,6 +2253,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index f5b4433142..259b8020e8 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2118,6 +2118,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 213853a1f1..e1171a34aa 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -168,6 +168,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 15dda47ba8..a521506506 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2198,6 +2198,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 3ffd49cbfb..aba642460c 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2178,6 +2178,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 2bccbe960a..d3d653d144 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2175,6 +2175,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 209f5f588b..a4ce56c34f 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2169,6 +2169,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 45d976790c..51fbf0b1e1 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2167,6 +2167,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index ab3156c917..5642781479 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2175,6 +2175,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index f8d0534156..10954ebee4 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2169,6 +2169,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index f56e5ad002..848cb2e599 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2216,6 +2216,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/paths.h b/sysdeps/unix/sysv/linux/paths.h
index 89686bcf88..b78dff7ae3 100644
--- a/sysdeps/unix/sysv/linux/paths.h
+++ b/sysdeps/unix/sysv/linux/paths.h
@@ -47,7 +47,8 @@
 #define	_PATH_GSHADOW	"/etc/gshadow"
 #define	_PATH_KLOG	"/proc/kmsg"
 #define	_PATH_KMEM	"/dev/kmem"
-#define	_PATH_LASTLOG	"/var/log/lastlog"
+#define _PATH_LASTLOG_VER ".v2"
+#define	_PATH_LASTLOG	"/var/log/lastlog" _PATH_LASTLOG_VER
 #define	_PATH_MAILDIR	"/var/mail"
 #define	_PATH_MAN	"/usr/share/man"
 #define	_PATH_MEM	"/dev/mem"
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index cfb457400c..93e83fa602 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2225,6 +2225,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index e1fd74fbad..ec0b6d69b1 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2258,6 +2258,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index 5c9cdb33b4..f5bd1db3a0 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2088,6 +2088,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 4dcac4c766..27863e57af 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2378,6 +2378,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index 69bc04c36c..08c5a32d5d 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -1945,6 +1945,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index dc4a3223e6..88b6fa7fc9 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2145,6 +2145,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/s390/lastlog-compat.h b/sysdeps/unix/sysv/linux/s390/lastlog-compat.h
new file mode 100644
index 0000000000..56fadc3b3b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/lastlog-compat.h
@@ -0,0 +1,38 @@
+/* Compat lastlog definitions.  s390 definition.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _LASTLOG_COMPAT_H
+#define _LASTLOG_COMPAT_H 1
+
+/* The s390 changes its lastlog to 64-bit on glibc 2.9 without any handling
+   of old format.  The is_path_lastlog_compat assumes 64-bit as default.  */
+
+struct lastlog_compat
+{
+  int64_t ll_time;
+  char ll_line[UT_LINESIZE];
+  char ll_host[UT_HOSTSIZE];
+};
+
+static inline bool
+is_path_lastlog_compat (const char *file)
+{
+  return false;
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index cead75acc5..7bc5c8866b 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2212,6 +2212,8 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 31366dd7e6..e26a24fe65 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2113,6 +2113,8 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 6deb52d706..06143b0283 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2093,6 +2093,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index 17a141d5b9..eab2af349b 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2090,6 +2090,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index b64b351797..4783a8fa97 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2214,6 +2214,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index e3e01c29fc..47ded40426 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2141,6 +2141,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 9995da84a8..0d144a0c10 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2100,6 +2100,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index adccf45120..a3580872d3 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2197,6 +2197,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [glibc/azanella/y2038] login: Use 64-bit time on struct lastlog
@ 2021-02-26 20:41 Adhemerval Zanella
  0 siblings, 0 replies; 8+ messages in thread
From: Adhemerval Zanella @ 2021-02-26 20:41 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=354a24b04e978389748990e763649ec3d5bf4405

commit 354a24b04e978389748990e763649ec3d5bf4405
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Tue Aug 4 10:50:02 2020 -0300

    login: Use 64-bit time on struct lastlog
    
    The new struct has the same size on both 32-bit and 64-bit
    architectures.  As for utmp{x} 64-bit time_t support, a new file name
    is defined for _PATH_LASTLOG.
    
    Also two new symbols are added that read/write 'struct lastlog'
    entries, 'lastlog_read' and 'lastlog_write'.  Both are GNU extensions
    and handle the 32-bit entry operation if the argument is the old
    _PATH_LASTLOG path.
    
    Different than utmp{x}, no concurrent access is done (such as
    advisory locking).  I modeled these function on how program that
    access lastlog file uses (such as shadow-utils and util-linux).
    
    The s390 is the only architecture that already defined the
    'struct lastlog' with 64-bit time_t and to handle s390 has a specific
    lastlog-compat.h header where 'is_path_lastlog_compat' already
    return false (thus making both lastlog_read and lastlog_write
    always read/write registers with 64-bit ll_time).
    
    It also fixes BZ#25844 by adding the __attribute_nonstring__ on
    ll_line and ll_host.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.

Diff:
---
 bits/types/struct_lastlog.h                        | 10 +--
 login/Makefile                                     |  5 +-
 login/Versions                                     |  2 +
 .../struct_lastlog.h => login/lastlog-compat.h     | 27 ++++----
 login/lastlog_read.c                               | 71 +++++++++++++++++++
 login/lastlog_write.c                              | 59 ++++++++++++++++
 login/tst-lastlog.c                                | 79 ++++++++++++++++++++++
 login/tst-lastlog.root/tst-lastlog.script          |  6 ++
 login/utmp.h                                       | 11 +++
 sysdeps/generic/paths.h                            |  3 +-
 sysdeps/mach/hurd/i386/libc.abilist                |  2 +
 sysdeps/unix/sysv/linux/aarch64/libc.abilist       |  2 +
 sysdeps/unix/sysv/linux/alpha/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/arc/libc.abilist           |  2 +
 sysdeps/unix/sysv/linux/arm/be/libc.abilist        |  2 +
 sysdeps/unix/sysv/linux/arm/le/libc.abilist        |  2 +
 sysdeps/unix/sysv/linux/csky/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/hppa/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/i386/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/ia64/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/microblaze/be/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/microblaze/le/libc.abilist |  2 +
 .../unix/sysv/linux/mips/mips32/fpu/libc.abilist   |  2 +
 .../unix/sysv/linux/mips/mips32/nofpu/libc.abilist |  2 +
 .../unix/sysv/linux/mips/mips64/n32/libc.abilist   |  2 +
 .../unix/sysv/linux/mips/mips64/n64/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/nios2/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/paths.h                    |  3 +-
 .../sysv/linux/powerpc/powerpc32/fpu/libc.abilist  |  2 +
 .../linux/powerpc/powerpc32/nofpu/libc.abilist     |  2 +
 .../sysv/linux/powerpc/powerpc64/be/libc.abilist   |  2 +
 .../sysv/linux/powerpc/powerpc64/le/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist    |  2 +
 sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist    |  2 +
 sysdeps/unix/sysv/linux/s390/lastlog-compat.h      | 38 +++++++++++
 sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist  |  2 +
 sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist  |  2 +
 sysdeps/unix/sysv/linux/sh/be/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/sh/le/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/x86_64/64/libc.abilist     |  2 +
 sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist    |  2 +
 45 files changed, 357 insertions(+), 23 deletions(-)

diff --git a/bits/types/struct_lastlog.h b/bits/types/struct_lastlog.h
index 67ffec1b08..8c87958bec 100644
--- a/bits/types/struct_lastlog.h
+++ b/bits/types/struct_lastlog.h
@@ -24,11 +24,7 @@
    previous logins.  */
 struct lastlog
 {
-#if __WORDSIZE_TIME64_COMPAT32
-  int32_t ll_time;
-#else
-  __time_t ll_time;
-#endif
-  char ll_line[UT_LINESIZE];
-  char ll_host[UT_HOSTSIZE];
+  int64_t ll_time;
+  char ll_line[UT_LINESIZE] __attribute_nonstring__;
+  char ll_host[UT_HOSTSIZE] __attribute_nonstring__;
 };
diff --git a/login/Makefile b/login/Makefile
index b5569683fa..4b5a3f0d63 100644
--- a/login/Makefile
+++ b/login/Makefile
@@ -31,7 +31,8 @@ headers	:= utmp.h bits/utmp.h lastlog.h pty.h \
 routines := getlogin getlogin_r setlogin getlogin_r_chk \
 	    getutent getutent_r getutid getutline getutid_r getutline_r \
 	    utmp_file utmpname updwtmp getpt grantpt unlockpt ptsname \
-	    ptsname_r_chk utmp32 utmpx32 utmp-convert
+	    ptsname_r_chk utmp32 utmpx32 utmp-convert \
+	    lastlog_read lastlog_write
 
 CFLAGS-grantpt.c += -DLIBEXECDIR='"$(libexecdir)"'
 
@@ -50,7 +51,7 @@ tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \
   tst-pututxline-lockfail tst-pututxline-cache
 
 tests-container-internal := tst-utmp32
-tests-container := tst-utmp-default
+tests-container := tst-utmp-default tst-lastlog
 
 # Build the -lutil library with these extra functions.
 extra-libs      := libutil
diff --git a/login/Versions b/login/Versions
index d28ecdca9f..5751fdcb71 100644
--- a/login/Versions
+++ b/login/Versions
@@ -57,6 +57,8 @@ libc {
     getutxent;
     getutxid;
     getutxline;
+    lastlog_read;
+    lastlog_write;
     pututline;
     pututxline;
     updwtmp;
diff --git a/sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h b/login/lastlog-compat.h
similarity index 74%
rename from sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h
rename to login/lastlog-compat.h
index 1faa472ec8..687774a21e 100644
--- a/sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h
+++ b/login/lastlog-compat.h
@@ -1,4 +1,4 @@
-/* The 'struct lastlog' type.
+/* Compat lastlog definitions.
    Copyright (C) 2020 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,19 +16,22 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#ifndef _UTMP_H
-# error "Never include <bits/struct_lastlog.h> directly; use <utmp.h> instead."
-#endif
+#ifndef _LASTLOG_COMPAT_H
+#define _LASTLOG_COMPAT_H 1
+
+#include <string.h>
 
-/* The structure describing an entry in the database of
-   previous logins.  */
-struct lastlog
+struct lastlog_compat
 {
-#if __WORDSIZE == 32
-  int64_t ll_time;
-#else
-  __time_t ll_time;
-#endif
+  int32_t ll_time;
   char ll_line[UT_LINESIZE];
   char ll_host[UT_HOSTSIZE];
 };
+
+static inline bool
+is_path_lastlog_compat (const char *file)
+{
+  return strcmp (file, "/var/log/lastlog") == 0;
+}
+
+#endif
diff --git a/login/lastlog_read.c b/login/lastlog_read.c
new file mode 100644
index 0000000000..e2c6e82a15
--- /dev/null
+++ b/login/lastlog_read.c
@@ -0,0 +1,71 @@
+/* Read a lastlog entry.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <utmp.h>
+#include <stdbool.h>
+#include <not-cancel.h>
+#include <lastlog-compat.h>
+
+ssize_t
+lastlog_read (const char *file, uid_t uid, struct lastlog *ll)
+{
+  int fd = __open_nocancel (file, O_RDONLY | O_LARGEFILE | O_CLOEXEC);
+  if (fd == -1)
+    return -1;
+
+  size_t llsize;
+  struct lastlog_compat llcompat;
+  void *data;
+
+  if (is_path_lastlog_compat (file))
+    {
+      llsize = sizeof (struct lastlog_compat);
+      data = &llcompat;
+    }
+  else
+    {
+      llsize = sizeof (struct lastlog);
+      data = ll;
+    }
+
+  off64_t off = llsize * uid;
+  ssize_t r = __pread64_nocancel (fd, data, llsize, off);
+  __close_nocancel_nostatus (fd);
+
+  if (r == llsize && data == &llcompat)
+    {
+      ll->ll_time = llcompat.ll_time;
+      memcpy (ll->ll_line, llcompat.ll_line, UT_LINESIZE);
+      memcpy (ll->ll_host, llcompat.ll_host, UT_HOSTSIZE);
+    }
+
+  if (r == llsize)
+    {
+      if (data == &llcompat)
+	{
+	  ll->ll_time = llcompat.ll_time;
+	  memcpy (ll->ll_line, llcompat.ll_line, UT_LINESIZE);
+	  memcpy (ll->ll_host, llcompat.ll_host, UT_HOSTSIZE);
+	}
+      /* We need to return the expected 'struct lastlog' size in case of
+	 success.  */
+      r = sizeof (struct lastlog);
+    }
+
+  return r;
+}
diff --git a/login/lastlog_write.c b/login/lastlog_write.c
new file mode 100644
index 0000000000..f3aedcbdb7
--- /dev/null
+++ b/login/lastlog_write.c
@@ -0,0 +1,59 @@
+/* Write a lastlog entry.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <utmp.h>
+#include <stdbool.h>
+#include <not-cancel.h>
+#include <lastlog-compat.h>
+
+ssize_t
+lastlog_write (const char *file, uid_t uid, const struct lastlog *ll)
+{
+  int fd = __open_nocancel (file, O_WRONLY | O_LARGEFILE | O_CLOEXEC);
+  if (fd == -1)
+    return -1;
+
+  size_t llsize;
+  struct lastlog_compat llcompat;
+  const void *data;
+
+  if (is_path_lastlog_compat (file))
+    {
+      llcompat.ll_time = ll->ll_time;
+      memcpy (llcompat.ll_line, ll->ll_line, UT_LINESIZE);
+      memcpy (llcompat.ll_host, ll->ll_host, UT_HOSTSIZE);
+      llsize = sizeof (struct lastlog_compat);
+      data = &llcompat;
+    }
+  else
+    {
+      llsize = sizeof (struct lastlog);
+      data = ll;
+    }
+
+  off64_t off = llsize * uid;
+  ssize_t r = __pwrite64_nocancel (fd, data, llsize, off);
+  __close_nocancel_nostatus (fd);
+
+  /* We need to return the expected 'struct lastlog' size in case of
+     success.  */
+  if (r == llsize && data == &llcompat)
+    r = sizeof (struct lastlog);
+
+  return r;
+}
diff --git a/login/tst-lastlog.c b/login/tst-lastlog.c
new file mode 100644
index 0000000000..9376a6ddf4
--- /dev/null
+++ b/login/tst-lastlog.c
@@ -0,0 +1,79 @@
+/* Tests for lastlog read/write functions.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+#include <string.h>
+#include <utmp.h>
+
+#include <support/check.h>
+#include <support/temp_file.h>
+
+#include <stdio.h>
+
+static struct
+{
+  uid_t uid;
+  struct lastlog ll;
+} entry[] =
+{
+  { 0,    { .ll_time = 1000, .ll_line = "tty1" } },
+  { 1000, { .ll_time = 2000, .ll_line = "pts/0", .ll_host = "127.0.0.1" } },
+  { 20,   { .ll_time = 3000, .ll_line = "pts/1", .ll_host = "192.168.0.1" } },
+  { 30,   { .ll_time = 4000, .ll_line = "tty2" } },
+};
+const size_t entry_size = sizeof (entry) / sizeof (entry[0]);
+
+static void
+run_test (const char *filename)
+{
+  for (int n = 0; n < entry_size; n++)
+    TEST_COMPARE (lastlog_write (filename, entry[n].uid, &entry[n].ll),
+		  sizeof (struct lastlog));
+
+  for (int n = 0; n < entry_size; n++)
+    {
+      struct lastlog ll;
+      TEST_COMPARE (lastlog_read (filename, entry[n].uid, &ll),
+		    sizeof (struct lastlog));
+      TEST_COMPARE (ll.ll_time, entry[n].ll.ll_time);
+      TEST_COMPARE_BLOB (ll.ll_line, UT_LINESIZE,
+			 entry[n].ll.ll_line, UT_LINESIZE);
+      TEST_COMPARE_BLOB (ll.ll_host, UT_HOSTSIZE,
+			 entry[n].ll.ll_host, UT_HOSTSIZE);
+    }
+
+  /* Check with an non present uid.  */
+  {
+    struct lastlog ll;
+    TEST_COMPARE (lastlog_read (filename, 4000, &ll), 0);
+  }
+}
+
+static int
+do_test (void)
+{
+  /* The path triggers the read/write of compat (32-bit ll_time) entries.  */
+  run_test ("/var/run/lastlog");
+
+  /* Any other file handles new (64-bit ll_time) entries.  */
+  run_test ("/var/run/lastlog.v2");
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/login/tst-lastlog.root/tst-lastlog.script b/login/tst-lastlog.root/tst-lastlog.script
new file mode 100644
index 0000000000..ca34ce7021
--- /dev/null
+++ b/login/tst-lastlog.root/tst-lastlog.script
@@ -0,0 +1,6 @@
+mkdirp 0755 /var/run
+touch  0664 /var/run/lastlog
+touch  0664 /var/run/lastlog.v2
+
+# Must run localedef as root to write into default paths.
+su
diff --git a/login/utmp.h b/login/utmp.h
index 7fc2d5cdf1..02a445ee82 100644
--- a/login/utmp.h
+++ b/login/utmp.h
@@ -91,6 +91,17 @@ extern int getutline_r (const struct utmp *__line,
 
 #endif	/* Use misc.  */
 
+#ifdef __USE_GNU
+/* Read the struct lastlog LL with UID from file FILE.  */
+extern ssize_t lastlog_read (const char *__file, uid_t __uid,
+			     struct lastlog *__ll)
+     __THROW __nonnull ((1, 3));
+/* Write the struct lastlog LL with UID from file FILE.  */
+extern ssize_t lastlog_write (const char *__file, uid_t __uid,
+			      const struct lastlog *__ll)
+     __THROW __nonnull ((1, 3));
+#endif
+
 __END_DECLS
 
 #endif /* utmp.h  */
diff --git a/sysdeps/generic/paths.h b/sysdeps/generic/paths.h
index ab2980e14a..9321ad7294 100644
--- a/sysdeps/generic/paths.h
+++ b/sysdeps/generic/paths.h
@@ -46,7 +46,8 @@
 #define	_PATH_DRUM	"/dev/drum"
 #define	_PATH_GSHADOW	"/etc/gshadow"
 #define	_PATH_KMEM	"/dev/kmem"
-#define	_PATH_LASTLOG	"/var/log/lastlog"
+#define _PATH_LASTLOG_VER ".v2"
+#define	_PATH_LASTLOG	"/var/log/lastlog" _PATH_LASTLOG_VER
 #define	_PATH_MAILDIR	"/var/mail"
 #define	_PATH_MAN	"/usr/share/man"
 #define	_PATH_MEM	"/dev/mem"
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 3a657d5e0d..d5e44b181b 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2215,6 +2215,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 4f91e85ba0..1516f80402 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2183,6 +2183,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 764ea51779..5ac4b37c02 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2265,6 +2265,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index 2ebd24f3a6..cefb1394e8 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -1943,6 +1943,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index 5cfcb00ddb..8111b49085 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -167,6 +167,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index d140654389..4dba1f2f46 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -164,6 +164,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index 11aa688b83..a5ff3d90ca 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2127,6 +2127,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index 14eef860ac..89a0f11166 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2086,6 +2086,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index e1db1488a9..a7c408d18c 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2253,6 +2253,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index f5b4433142..259b8020e8 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2118,6 +2118,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index 213853a1f1..e1171a34aa 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -168,6 +168,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index 15dda47ba8..a521506506 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2198,6 +2198,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 3ffd49cbfb..aba642460c 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2178,6 +2178,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index 2bccbe960a..d3d653d144 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2175,6 +2175,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 209f5f588b..a4ce56c34f 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2169,6 +2169,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 45d976790c..51fbf0b1e1 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2167,6 +2167,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index ab3156c917..5642781479 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2175,6 +2175,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index f8d0534156..10954ebee4 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2169,6 +2169,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index f56e5ad002..848cb2e599 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2216,6 +2216,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/paths.h b/sysdeps/unix/sysv/linux/paths.h
index 89686bcf88..b78dff7ae3 100644
--- a/sysdeps/unix/sysv/linux/paths.h
+++ b/sysdeps/unix/sysv/linux/paths.h
@@ -47,7 +47,8 @@
 #define	_PATH_GSHADOW	"/etc/gshadow"
 #define	_PATH_KLOG	"/proc/kmsg"
 #define	_PATH_KMEM	"/dev/kmem"
-#define	_PATH_LASTLOG	"/var/log/lastlog"
+#define _PATH_LASTLOG_VER ".v2"
+#define	_PATH_LASTLOG	"/var/log/lastlog" _PATH_LASTLOG_VER
 #define	_PATH_MAILDIR	"/var/mail"
 #define	_PATH_MAN	"/usr/share/man"
 #define	_PATH_MEM	"/dev/mem"
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index cfb457400c..93e83fa602 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2225,6 +2225,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index e1fd74fbad..ec0b6d69b1 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2258,6 +2258,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index 5c9cdb33b4..f5bd1db3a0 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2088,6 +2088,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 4dcac4c766..27863e57af 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2378,6 +2378,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index 69bc04c36c..08c5a32d5d 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -1945,6 +1945,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index dc4a3223e6..88b6fa7fc9 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2145,6 +2145,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/s390/lastlog-compat.h b/sysdeps/unix/sysv/linux/s390/lastlog-compat.h
new file mode 100644
index 0000000000..56fadc3b3b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/lastlog-compat.h
@@ -0,0 +1,38 @@
+/* Compat lastlog definitions.  s390 definition.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _LASTLOG_COMPAT_H
+#define _LASTLOG_COMPAT_H 1
+
+/* The s390 changes its lastlog to 64-bit on glibc 2.9 without any handling
+   of old format.  The is_path_lastlog_compat assumes 64-bit as default.  */
+
+struct lastlog_compat
+{
+  int64_t ll_time;
+  char ll_line[UT_LINESIZE];
+  char ll_host[UT_HOSTSIZE];
+};
+
+static inline bool
+is_path_lastlog_compat (const char *file)
+{
+  return false;
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index cead75acc5..7bc5c8866b 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2212,6 +2212,8 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index 31366dd7e6..e26a24fe65 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2113,6 +2113,8 @@ GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
 GLIBC_2.34 __libc_start_main F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index 6deb52d706..06143b0283 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2093,6 +2093,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index 17a141d5b9..eab2af349b 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2090,6 +2090,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index b64b351797..4783a8fa97 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2214,6 +2214,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index e3e01c29fc..47ded40426 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2141,6 +2141,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 9995da84a8..0d144a0c10 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2100,6 +2100,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index adccf45120..a3580872d3 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2197,6 +2197,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [glibc/azanella/y2038] login: Use 64-bit time on struct lastlog
@ 2021-02-23 20:39 Adhemerval Zanella
  0 siblings, 0 replies; 8+ messages in thread
From: Adhemerval Zanella @ 2021-02-23 20:39 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=c83630549c5be777cd23125239ecccf10605e081

commit c83630549c5be777cd23125239ecccf10605e081
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Tue Aug 4 10:50:02 2020 -0300

    login: Use 64-bit time on struct lastlog
    
    The new struct has the same size on both 32-bit and 64-bit
    architectures.  As for utmp{x} 64-bit time_t support, a new file name
    is defined for _PATH_LASTLOG.
    
    Also two new symbols are added that read/write 'struct lastlog'
    entries, 'lastlog_read' and 'lastlog_write'.  Both are GNU extensions
    and handle the 32-bit entry operation if the argument is the old
    _PATH_LASTLOG path.
    
    Different than utmp{x}, no concurrent access is done (such as
    advisory locking).  I modeled these function on how program that
    access lastlog file uses (such as shadow-utils and util-linux).
    
    The s390 is the only architecture that already defined the
    'struct lastlog' with 64-bit time_t and to handle s390 has a specific
    lastlog-compat.h header where 'is_path_lastlog_compat' already
    return false (thus making both lastlog_read and lastlog_write
    always read/write registers with 64-bit ll_time).
    
    It also fixes BZ#25844 by adding the __attribute_nonstring__ on
    ll_line and ll_host.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.

Diff:
---
 bits/types/struct_lastlog.h                        | 10 +--
 login/Makefile                                     |  5 +-
 login/Versions                                     |  2 +
 .../struct_lastlog.h => login/lastlog-compat.h     | 27 ++++----
 login/lastlog_read.c                               | 71 +++++++++++++++++++
 login/lastlog_write.c                              | 59 ++++++++++++++++
 login/tst-lastlog.c                                | 79 ++++++++++++++++++++++
 login/tst-lastlog.root/tst-lastlog.script          |  6 ++
 login/utmp.h                                       | 11 +++
 sysdeps/generic/paths.h                            |  3 +-
 sysdeps/mach/hurd/i386/libc.abilist                |  2 +
 sysdeps/unix/sysv/linux/aarch64/libc.abilist       |  2 +
 sysdeps/unix/sysv/linux/alpha/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/arc/libc.abilist           |  2 +
 sysdeps/unix/sysv/linux/arm/be/libc.abilist        |  2 +
 sysdeps/unix/sysv/linux/arm/le/libc.abilist        |  2 +
 sysdeps/unix/sysv/linux/csky/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/hppa/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/i386/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/ia64/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/microblaze/be/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/microblaze/le/libc.abilist |  2 +
 .../unix/sysv/linux/mips/mips32/fpu/libc.abilist   |  2 +
 .../unix/sysv/linux/mips/mips32/nofpu/libc.abilist |  2 +
 .../unix/sysv/linux/mips/mips64/n32/libc.abilist   |  2 +
 .../unix/sysv/linux/mips/mips64/n64/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/nios2/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/paths.h                    |  3 +-
 .../sysv/linux/powerpc/powerpc32/fpu/libc.abilist  |  2 +
 .../linux/powerpc/powerpc32/nofpu/libc.abilist     |  2 +
 .../sysv/linux/powerpc/powerpc64/be/libc.abilist   |  2 +
 .../sysv/linux/powerpc/powerpc64/le/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist    |  2 +
 sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist    |  2 +
 sysdeps/unix/sysv/linux/s390/lastlog-compat.h      | 38 +++++++++++
 sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist  |  2 +
 sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist  |  2 +
 sysdeps/unix/sysv/linux/sh/be/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/sh/le/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/x86_64/64/libc.abilist     |  2 +
 sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist    |  2 +
 45 files changed, 357 insertions(+), 23 deletions(-)

diff --git a/bits/types/struct_lastlog.h b/bits/types/struct_lastlog.h
index 67ffec1b08..8c87958bec 100644
--- a/bits/types/struct_lastlog.h
+++ b/bits/types/struct_lastlog.h
@@ -24,11 +24,7 @@
    previous logins.  */
 struct lastlog
 {
-#if __WORDSIZE_TIME64_COMPAT32
-  int32_t ll_time;
-#else
-  __time_t ll_time;
-#endif
-  char ll_line[UT_LINESIZE];
-  char ll_host[UT_HOSTSIZE];
+  int64_t ll_time;
+  char ll_line[UT_LINESIZE] __attribute_nonstring__;
+  char ll_host[UT_HOSTSIZE] __attribute_nonstring__;
 };
diff --git a/login/Makefile b/login/Makefile
index b5569683fa..4b5a3f0d63 100644
--- a/login/Makefile
+++ b/login/Makefile
@@ -31,7 +31,8 @@ headers	:= utmp.h bits/utmp.h lastlog.h pty.h \
 routines := getlogin getlogin_r setlogin getlogin_r_chk \
 	    getutent getutent_r getutid getutline getutid_r getutline_r \
 	    utmp_file utmpname updwtmp getpt grantpt unlockpt ptsname \
-	    ptsname_r_chk utmp32 utmpx32 utmp-convert
+	    ptsname_r_chk utmp32 utmpx32 utmp-convert \
+	    lastlog_read lastlog_write
 
 CFLAGS-grantpt.c += -DLIBEXECDIR='"$(libexecdir)"'
 
@@ -50,7 +51,7 @@ tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \
   tst-pututxline-lockfail tst-pututxline-cache
 
 tests-container-internal := tst-utmp32
-tests-container := tst-utmp-default
+tests-container := tst-utmp-default tst-lastlog
 
 # Build the -lutil library with these extra functions.
 extra-libs      := libutil
diff --git a/login/Versions b/login/Versions
index d28ecdca9f..5751fdcb71 100644
--- a/login/Versions
+++ b/login/Versions
@@ -57,6 +57,8 @@ libc {
     getutxent;
     getutxid;
     getutxline;
+    lastlog_read;
+    lastlog_write;
     pututline;
     pututxline;
     updwtmp;
diff --git a/sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h b/login/lastlog-compat.h
similarity index 74%
rename from sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h
rename to login/lastlog-compat.h
index 1faa472ec8..687774a21e 100644
--- a/sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h
+++ b/login/lastlog-compat.h
@@ -1,4 +1,4 @@
-/* The 'struct lastlog' type.
+/* Compat lastlog definitions.
    Copyright (C) 2020 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,19 +16,22 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#ifndef _UTMP_H
-# error "Never include <bits/struct_lastlog.h> directly; use <utmp.h> instead."
-#endif
+#ifndef _LASTLOG_COMPAT_H
+#define _LASTLOG_COMPAT_H 1
+
+#include <string.h>
 
-/* The structure describing an entry in the database of
-   previous logins.  */
-struct lastlog
+struct lastlog_compat
 {
-#if __WORDSIZE == 32
-  int64_t ll_time;
-#else
-  __time_t ll_time;
-#endif
+  int32_t ll_time;
   char ll_line[UT_LINESIZE];
   char ll_host[UT_HOSTSIZE];
 };
+
+static inline bool
+is_path_lastlog_compat (const char *file)
+{
+  return strcmp (file, "/var/log/lastlog") == 0;
+}
+
+#endif
diff --git a/login/lastlog_read.c b/login/lastlog_read.c
new file mode 100644
index 0000000000..e2c6e82a15
--- /dev/null
+++ b/login/lastlog_read.c
@@ -0,0 +1,71 @@
+/* Read a lastlog entry.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <utmp.h>
+#include <stdbool.h>
+#include <not-cancel.h>
+#include <lastlog-compat.h>
+
+ssize_t
+lastlog_read (const char *file, uid_t uid, struct lastlog *ll)
+{
+  int fd = __open_nocancel (file, O_RDONLY | O_LARGEFILE | O_CLOEXEC);
+  if (fd == -1)
+    return -1;
+
+  size_t llsize;
+  struct lastlog_compat llcompat;
+  void *data;
+
+  if (is_path_lastlog_compat (file))
+    {
+      llsize = sizeof (struct lastlog_compat);
+      data = &llcompat;
+    }
+  else
+    {
+      llsize = sizeof (struct lastlog);
+      data = ll;
+    }
+
+  off64_t off = llsize * uid;
+  ssize_t r = __pread64_nocancel (fd, data, llsize, off);
+  __close_nocancel_nostatus (fd);
+
+  if (r == llsize && data == &llcompat)
+    {
+      ll->ll_time = llcompat.ll_time;
+      memcpy (ll->ll_line, llcompat.ll_line, UT_LINESIZE);
+      memcpy (ll->ll_host, llcompat.ll_host, UT_HOSTSIZE);
+    }
+
+  if (r == llsize)
+    {
+      if (data == &llcompat)
+	{
+	  ll->ll_time = llcompat.ll_time;
+	  memcpy (ll->ll_line, llcompat.ll_line, UT_LINESIZE);
+	  memcpy (ll->ll_host, llcompat.ll_host, UT_HOSTSIZE);
+	}
+      /* We need to return the expected 'struct lastlog' size in case of
+	 success.  */
+      r = sizeof (struct lastlog);
+    }
+
+  return r;
+}
diff --git a/login/lastlog_write.c b/login/lastlog_write.c
new file mode 100644
index 0000000000..f3aedcbdb7
--- /dev/null
+++ b/login/lastlog_write.c
@@ -0,0 +1,59 @@
+/* Write a lastlog entry.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <utmp.h>
+#include <stdbool.h>
+#include <not-cancel.h>
+#include <lastlog-compat.h>
+
+ssize_t
+lastlog_write (const char *file, uid_t uid, const struct lastlog *ll)
+{
+  int fd = __open_nocancel (file, O_WRONLY | O_LARGEFILE | O_CLOEXEC);
+  if (fd == -1)
+    return -1;
+
+  size_t llsize;
+  struct lastlog_compat llcompat;
+  const void *data;
+
+  if (is_path_lastlog_compat (file))
+    {
+      llcompat.ll_time = ll->ll_time;
+      memcpy (llcompat.ll_line, ll->ll_line, UT_LINESIZE);
+      memcpy (llcompat.ll_host, ll->ll_host, UT_HOSTSIZE);
+      llsize = sizeof (struct lastlog_compat);
+      data = &llcompat;
+    }
+  else
+    {
+      llsize = sizeof (struct lastlog);
+      data = ll;
+    }
+
+  off64_t off = llsize * uid;
+  ssize_t r = __pwrite64_nocancel (fd, data, llsize, off);
+  __close_nocancel_nostatus (fd);
+
+  /* We need to return the expected 'struct lastlog' size in case of
+     success.  */
+  if (r == llsize && data == &llcompat)
+    r = sizeof (struct lastlog);
+
+  return r;
+}
diff --git a/login/tst-lastlog.c b/login/tst-lastlog.c
new file mode 100644
index 0000000000..9376a6ddf4
--- /dev/null
+++ b/login/tst-lastlog.c
@@ -0,0 +1,79 @@
+/* Tests for lastlog read/write functions.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+#include <string.h>
+#include <utmp.h>
+
+#include <support/check.h>
+#include <support/temp_file.h>
+
+#include <stdio.h>
+
+static struct
+{
+  uid_t uid;
+  struct lastlog ll;
+} entry[] =
+{
+  { 0,    { .ll_time = 1000, .ll_line = "tty1" } },
+  { 1000, { .ll_time = 2000, .ll_line = "pts/0", .ll_host = "127.0.0.1" } },
+  { 20,   { .ll_time = 3000, .ll_line = "pts/1", .ll_host = "192.168.0.1" } },
+  { 30,   { .ll_time = 4000, .ll_line = "tty2" } },
+};
+const size_t entry_size = sizeof (entry) / sizeof (entry[0]);
+
+static void
+run_test (const char *filename)
+{
+  for (int n = 0; n < entry_size; n++)
+    TEST_COMPARE (lastlog_write (filename, entry[n].uid, &entry[n].ll),
+		  sizeof (struct lastlog));
+
+  for (int n = 0; n < entry_size; n++)
+    {
+      struct lastlog ll;
+      TEST_COMPARE (lastlog_read (filename, entry[n].uid, &ll),
+		    sizeof (struct lastlog));
+      TEST_COMPARE (ll.ll_time, entry[n].ll.ll_time);
+      TEST_COMPARE_BLOB (ll.ll_line, UT_LINESIZE,
+			 entry[n].ll.ll_line, UT_LINESIZE);
+      TEST_COMPARE_BLOB (ll.ll_host, UT_HOSTSIZE,
+			 entry[n].ll.ll_host, UT_HOSTSIZE);
+    }
+
+  /* Check with an non present uid.  */
+  {
+    struct lastlog ll;
+    TEST_COMPARE (lastlog_read (filename, 4000, &ll), 0);
+  }
+}
+
+static int
+do_test (void)
+{
+  /* The path triggers the read/write of compat (32-bit ll_time) entries.  */
+  run_test ("/var/run/lastlog");
+
+  /* Any other file handles new (64-bit ll_time) entries.  */
+  run_test ("/var/run/lastlog.v2");
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/login/tst-lastlog.root/tst-lastlog.script b/login/tst-lastlog.root/tst-lastlog.script
new file mode 100644
index 0000000000..ca34ce7021
--- /dev/null
+++ b/login/tst-lastlog.root/tst-lastlog.script
@@ -0,0 +1,6 @@
+mkdirp 0755 /var/run
+touch  0664 /var/run/lastlog
+touch  0664 /var/run/lastlog.v2
+
+# Must run localedef as root to write into default paths.
+su
diff --git a/login/utmp.h b/login/utmp.h
index 7fc2d5cdf1..02a445ee82 100644
--- a/login/utmp.h
+++ b/login/utmp.h
@@ -91,6 +91,17 @@ extern int getutline_r (const struct utmp *__line,
 
 #endif	/* Use misc.  */
 
+#ifdef __USE_GNU
+/* Read the struct lastlog LL with UID from file FILE.  */
+extern ssize_t lastlog_read (const char *__file, uid_t __uid,
+			     struct lastlog *__ll)
+     __THROW __nonnull ((1, 3));
+/* Write the struct lastlog LL with UID from file FILE.  */
+extern ssize_t lastlog_write (const char *__file, uid_t __uid,
+			      const struct lastlog *__ll)
+     __THROW __nonnull ((1, 3));
+#endif
+
 __END_DECLS
 
 #endif /* utmp.h  */
diff --git a/sysdeps/generic/paths.h b/sysdeps/generic/paths.h
index ab2980e14a..9321ad7294 100644
--- a/sysdeps/generic/paths.h
+++ b/sysdeps/generic/paths.h
@@ -46,7 +46,8 @@
 #define	_PATH_DRUM	"/dev/drum"
 #define	_PATH_GSHADOW	"/etc/gshadow"
 #define	_PATH_KMEM	"/dev/kmem"
-#define	_PATH_LASTLOG	"/var/log/lastlog"
+#define _PATH_LASTLOG_VER ".v2"
+#define	_PATH_LASTLOG	"/var/log/lastlog" _PATH_LASTLOG_VER
 #define	_PATH_MAILDIR	"/var/mail"
 #define	_PATH_MAN	"/usr/share/man"
 #define	_PATH_MEM	"/dev/mem"
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 77589e9aab..c21462d7c2 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2214,6 +2214,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 5703811d47..6359fbe5d0 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2182,6 +2182,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 556144b40a..d78825d9a3 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2264,6 +2264,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index 3e01139bcc..eb5e302098 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -1942,6 +1942,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index ffc3be5255..eb3e165ce8 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -166,6 +166,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index cca9d7b2d8..2e7dbbe7df 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -163,6 +163,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index b11eefe55e..fd4fb4a9a9 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2126,6 +2126,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index f53f9d3dcc..8530ed550d 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2085,6 +2085,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 8604b9ba12..51b3d94801 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2252,6 +2252,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 75a8b98445..14299fa2aa 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2117,6 +2117,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index e293d0e766..113d895744 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -167,6 +167,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index ef071cd43f..b446ee38fd 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2197,6 +2197,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 7861c80ac2..b5b5ed8fea 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2177,6 +2177,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index c0aa1dd398..794cdb5069 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2174,6 +2174,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 10b83a39e5..ab50ed5c78 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2168,6 +2168,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 51cde431b8..e64ccb03b0 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2166,6 +2166,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 5adbd9019e..688336b729 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2174,6 +2174,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 9870c6d28a..91003c71e8 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2168,6 +2168,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 49f615353b..522c733a27 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2215,6 +2215,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/paths.h b/sysdeps/unix/sysv/linux/paths.h
index 89686bcf88..b78dff7ae3 100644
--- a/sysdeps/unix/sysv/linux/paths.h
+++ b/sysdeps/unix/sysv/linux/paths.h
@@ -47,7 +47,8 @@
 #define	_PATH_GSHADOW	"/etc/gshadow"
 #define	_PATH_KLOG	"/proc/kmsg"
 #define	_PATH_KMEM	"/dev/kmem"
-#define	_PATH_LASTLOG	"/var/log/lastlog"
+#define _PATH_LASTLOG_VER ".v2"
+#define	_PATH_LASTLOG	"/var/log/lastlog" _PATH_LASTLOG_VER
 #define	_PATH_MAILDIR	"/var/mail"
 #define	_PATH_MAN	"/usr/share/man"
 #define	_PATH_MEM	"/dev/mem"
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index b349bde439..99bc2a0df6 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2224,6 +2224,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index 43b2aabe84..156b336bfe 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2257,6 +2257,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index 7f02c58ee7..0b387f1b6b 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2087,6 +2087,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 2da63c5a70..677435cf1a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2377,6 +2377,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index 216e14cba2..537c5d61ad 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -1944,6 +1944,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index a34560861b..189a2ccf55 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2144,6 +2144,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/s390/lastlog-compat.h b/sysdeps/unix/sysv/linux/s390/lastlog-compat.h
new file mode 100644
index 0000000000..56fadc3b3b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/lastlog-compat.h
@@ -0,0 +1,38 @@
+/* Compat lastlog definitions.  s390 definition.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _LASTLOG_COMPAT_H
+#define _LASTLOG_COMPAT_H 1
+
+/* The s390 changes its lastlog to 64-bit on glibc 2.9 without any handling
+   of old format.  The is_path_lastlog_compat assumes 64-bit as default.  */
+
+struct lastlog_compat
+{
+  int64_t ll_time;
+  char ll_line[UT_LINESIZE];
+  char ll_host[UT_HOSTSIZE];
+};
+
+static inline bool
+is_path_lastlog_compat (const char *file)
+{
+  return false;
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index a66426eb4d..00d9eba7cd 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2211,6 +2211,8 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index ab351873ae..b823639610 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2112,6 +2112,8 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index b5b3b6c247..84d050ff2f 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2092,6 +2092,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index a0f1547fbf..da6cf58a8c 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2089,6 +2089,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index c76547d839..a678baade9 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2213,6 +2213,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 75a0132c20..caaf400f53 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2140,6 +2140,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 14bbd3450a..a3b5e44e00 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2099,6 +2099,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 95b58039e0..e088e91ae2 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2196,6 +2196,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [glibc/azanella/y2038] login: Use 64-bit time on struct lastlog
@ 2021-02-23 12:37 Adhemerval Zanella
  0 siblings, 0 replies; 8+ messages in thread
From: Adhemerval Zanella @ 2021-02-23 12:37 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=343a81eb9030a17464c0484d44ebd638f8af9ad2

commit 343a81eb9030a17464c0484d44ebd638f8af9ad2
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date:   Tue Aug 4 10:50:02 2020 -0300

    login: Use 64-bit time on struct lastlog
    
    The new struct has the same size on both 32-bit and 64-bit
    architectures.  As for utmp{x} 64-bit time_t support, a new file name
    is defined for _PATH_LASTLOG.
    
    Also two new symbols are added that read/write 'struct lastlog'
    entries, 'lastlog_read' and 'lastlog_write'.  Both are GNU extensions
    and handle the 32-bit entry operation if the argument is the old
    _PATH_LASTLOG path.
    
    Different than utmp{x}, no concurrent access is done (such as
    advisory locking).  I modeled these function on how program that
    access lastlog file uses (such as shadow-utils and util-linux).
    
    The s390 is the only architecture that already defined the
    'struct lastlog' with 64-bit time_t and to handle s390 has a specific
    lastlog-compat.h header where 'is_path_lastlog_compat' already
    return false (thus making both lastlog_read and lastlog_write
    always read/write registers with 64-bit ll_time).
    
    It also fixes BZ#25844 by adding the __attribute_nonstring__ on
    ll_line and ll_host.
    
    Checked on x86_64-linux-gnu and i686-linux-gnu.

Diff:
---
 bits/types/struct_lastlog.h                        | 10 +--
 login/Makefile                                     |  5 +-
 login/Versions                                     |  2 +
 .../struct_lastlog.h => login/lastlog-compat.h     | 27 ++++----
 login/lastlog_read.c                               | 71 +++++++++++++++++++
 login/lastlog_write.c                              | 59 ++++++++++++++++
 login/tst-lastlog.c                                | 79 ++++++++++++++++++++++
 login/tst-lastlog.root/tst-lastlog.script          |  6 ++
 login/utmp.h                                       | 11 +++
 sysdeps/generic/paths.h                            |  3 +-
 sysdeps/mach/hurd/i386/libc.abilist                |  2 +
 sysdeps/unix/sysv/linux/aarch64/libc.abilist       |  2 +
 sysdeps/unix/sysv/linux/alpha/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/arc/libc.abilist           |  2 +
 sysdeps/unix/sysv/linux/arm/be/libc.abilist        |  2 +
 sysdeps/unix/sysv/linux/arm/le/libc.abilist        |  2 +
 sysdeps/unix/sysv/linux/csky/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/hppa/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/i386/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/ia64/libc.abilist          |  2 +
 sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/microblaze/be/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/microblaze/le/libc.abilist |  2 +
 .../unix/sysv/linux/mips/mips32/fpu/libc.abilist   |  2 +
 .../unix/sysv/linux/mips/mips32/nofpu/libc.abilist |  2 +
 .../unix/sysv/linux/mips/mips64/n32/libc.abilist   |  2 +
 .../unix/sysv/linux/mips/mips64/n64/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/nios2/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/paths.h                    |  3 +-
 .../sysv/linux/powerpc/powerpc32/fpu/libc.abilist  |  2 +
 .../linux/powerpc/powerpc32/nofpu/libc.abilist     |  2 +
 .../sysv/linux/powerpc/powerpc64/be/libc.abilist   |  2 +
 .../sysv/linux/powerpc/powerpc64/le/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist    |  2 +
 sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist    |  2 +
 sysdeps/unix/sysv/linux/s390/lastlog-compat.h      | 38 +++++++++++
 sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist  |  2 +
 sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist  |  2 +
 sysdeps/unix/sysv/linux/sh/be/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/sh/le/libc.abilist         |  2 +
 sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist |  2 +
 sysdeps/unix/sysv/linux/x86_64/64/libc.abilist     |  2 +
 sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist    |  2 +
 45 files changed, 357 insertions(+), 23 deletions(-)

diff --git a/bits/types/struct_lastlog.h b/bits/types/struct_lastlog.h
index 67ffec1b08..8c87958bec 100644
--- a/bits/types/struct_lastlog.h
+++ b/bits/types/struct_lastlog.h
@@ -24,11 +24,7 @@
    previous logins.  */
 struct lastlog
 {
-#if __WORDSIZE_TIME64_COMPAT32
-  int32_t ll_time;
-#else
-  __time_t ll_time;
-#endif
-  char ll_line[UT_LINESIZE];
-  char ll_host[UT_HOSTSIZE];
+  int64_t ll_time;
+  char ll_line[UT_LINESIZE] __attribute_nonstring__;
+  char ll_host[UT_HOSTSIZE] __attribute_nonstring__;
 };
diff --git a/login/Makefile b/login/Makefile
index b5569683fa..4b5a3f0d63 100644
--- a/login/Makefile
+++ b/login/Makefile
@@ -31,7 +31,8 @@ headers	:= utmp.h bits/utmp.h lastlog.h pty.h \
 routines := getlogin getlogin_r setlogin getlogin_r_chk \
 	    getutent getutent_r getutid getutline getutid_r getutline_r \
 	    utmp_file utmpname updwtmp getpt grantpt unlockpt ptsname \
-	    ptsname_r_chk utmp32 utmpx32 utmp-convert
+	    ptsname_r_chk utmp32 utmpx32 utmp-convert \
+	    lastlog_read lastlog_write
 
 CFLAGS-grantpt.c += -DLIBEXECDIR='"$(libexecdir)"'
 
@@ -50,7 +51,7 @@ tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin tst-updwtmpx \
   tst-pututxline-lockfail tst-pututxline-cache
 
 tests-container-internal := tst-utmp32
-tests-container := tst-utmp-default
+tests-container := tst-utmp-default tst-lastlog
 
 # Build the -lutil library with these extra functions.
 extra-libs      := libutil
diff --git a/login/Versions b/login/Versions
index d28ecdca9f..5751fdcb71 100644
--- a/login/Versions
+++ b/login/Versions
@@ -57,6 +57,8 @@ libc {
     getutxent;
     getutxid;
     getutxline;
+    lastlog_read;
+    lastlog_write;
     pututline;
     pututxline;
     updwtmp;
diff --git a/sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h b/login/lastlog-compat.h
similarity index 74%
rename from sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h
rename to login/lastlog-compat.h
index 1faa472ec8..687774a21e 100644
--- a/sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h
+++ b/login/lastlog-compat.h
@@ -1,4 +1,4 @@
-/* The 'struct lastlog' type.
+/* Compat lastlog definitions.
    Copyright (C) 2020 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,19 +16,22 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#ifndef _UTMP_H
-# error "Never include <bits/struct_lastlog.h> directly; use <utmp.h> instead."
-#endif
+#ifndef _LASTLOG_COMPAT_H
+#define _LASTLOG_COMPAT_H 1
+
+#include <string.h>
 
-/* The structure describing an entry in the database of
-   previous logins.  */
-struct lastlog
+struct lastlog_compat
 {
-#if __WORDSIZE == 32
-  int64_t ll_time;
-#else
-  __time_t ll_time;
-#endif
+  int32_t ll_time;
   char ll_line[UT_LINESIZE];
   char ll_host[UT_HOSTSIZE];
 };
+
+static inline bool
+is_path_lastlog_compat (const char *file)
+{
+  return strcmp (file, "/var/log/lastlog") == 0;
+}
+
+#endif
diff --git a/login/lastlog_read.c b/login/lastlog_read.c
new file mode 100644
index 0000000000..e2c6e82a15
--- /dev/null
+++ b/login/lastlog_read.c
@@ -0,0 +1,71 @@
+/* Read a lastlog entry.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <utmp.h>
+#include <stdbool.h>
+#include <not-cancel.h>
+#include <lastlog-compat.h>
+
+ssize_t
+lastlog_read (const char *file, uid_t uid, struct lastlog *ll)
+{
+  int fd = __open_nocancel (file, O_RDONLY | O_LARGEFILE | O_CLOEXEC);
+  if (fd == -1)
+    return -1;
+
+  size_t llsize;
+  struct lastlog_compat llcompat;
+  void *data;
+
+  if (is_path_lastlog_compat (file))
+    {
+      llsize = sizeof (struct lastlog_compat);
+      data = &llcompat;
+    }
+  else
+    {
+      llsize = sizeof (struct lastlog);
+      data = ll;
+    }
+
+  off64_t off = llsize * uid;
+  ssize_t r = __pread64_nocancel (fd, data, llsize, off);
+  __close_nocancel_nostatus (fd);
+
+  if (r == llsize && data == &llcompat)
+    {
+      ll->ll_time = llcompat.ll_time;
+      memcpy (ll->ll_line, llcompat.ll_line, UT_LINESIZE);
+      memcpy (ll->ll_host, llcompat.ll_host, UT_HOSTSIZE);
+    }
+
+  if (r == llsize)
+    {
+      if (data == &llcompat)
+	{
+	  ll->ll_time = llcompat.ll_time;
+	  memcpy (ll->ll_line, llcompat.ll_line, UT_LINESIZE);
+	  memcpy (ll->ll_host, llcompat.ll_host, UT_HOSTSIZE);
+	}
+      /* We need to return the expected 'struct lastlog' size in case of
+	 success.  */
+      r = sizeof (struct lastlog);
+    }
+
+  return r;
+}
diff --git a/login/lastlog_write.c b/login/lastlog_write.c
new file mode 100644
index 0000000000..f3aedcbdb7
--- /dev/null
+++ b/login/lastlog_write.c
@@ -0,0 +1,59 @@
+/* Write a lastlog entry.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <utmp.h>
+#include <stdbool.h>
+#include <not-cancel.h>
+#include <lastlog-compat.h>
+
+ssize_t
+lastlog_write (const char *file, uid_t uid, const struct lastlog *ll)
+{
+  int fd = __open_nocancel (file, O_WRONLY | O_LARGEFILE | O_CLOEXEC);
+  if (fd == -1)
+    return -1;
+
+  size_t llsize;
+  struct lastlog_compat llcompat;
+  const void *data;
+
+  if (is_path_lastlog_compat (file))
+    {
+      llcompat.ll_time = ll->ll_time;
+      memcpy (llcompat.ll_line, ll->ll_line, UT_LINESIZE);
+      memcpy (llcompat.ll_host, ll->ll_host, UT_HOSTSIZE);
+      llsize = sizeof (struct lastlog_compat);
+      data = &llcompat;
+    }
+  else
+    {
+      llsize = sizeof (struct lastlog);
+      data = ll;
+    }
+
+  off64_t off = llsize * uid;
+  ssize_t r = __pwrite64_nocancel (fd, data, llsize, off);
+  __close_nocancel_nostatus (fd);
+
+  /* We need to return the expected 'struct lastlog' size in case of
+     success.  */
+  if (r == llsize && data == &llcompat)
+    r = sizeof (struct lastlog);
+
+  return r;
+}
diff --git a/login/tst-lastlog.c b/login/tst-lastlog.c
new file mode 100644
index 0000000000..9376a6ddf4
--- /dev/null
+++ b/login/tst-lastlog.c
@@ -0,0 +1,79 @@
+/* Tests for lastlog read/write functions.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+#include <string.h>
+#include <utmp.h>
+
+#include <support/check.h>
+#include <support/temp_file.h>
+
+#include <stdio.h>
+
+static struct
+{
+  uid_t uid;
+  struct lastlog ll;
+} entry[] =
+{
+  { 0,    { .ll_time = 1000, .ll_line = "tty1" } },
+  { 1000, { .ll_time = 2000, .ll_line = "pts/0", .ll_host = "127.0.0.1" } },
+  { 20,   { .ll_time = 3000, .ll_line = "pts/1", .ll_host = "192.168.0.1" } },
+  { 30,   { .ll_time = 4000, .ll_line = "tty2" } },
+};
+const size_t entry_size = sizeof (entry) / sizeof (entry[0]);
+
+static void
+run_test (const char *filename)
+{
+  for (int n = 0; n < entry_size; n++)
+    TEST_COMPARE (lastlog_write (filename, entry[n].uid, &entry[n].ll),
+		  sizeof (struct lastlog));
+
+  for (int n = 0; n < entry_size; n++)
+    {
+      struct lastlog ll;
+      TEST_COMPARE (lastlog_read (filename, entry[n].uid, &ll),
+		    sizeof (struct lastlog));
+      TEST_COMPARE (ll.ll_time, entry[n].ll.ll_time);
+      TEST_COMPARE_BLOB (ll.ll_line, UT_LINESIZE,
+			 entry[n].ll.ll_line, UT_LINESIZE);
+      TEST_COMPARE_BLOB (ll.ll_host, UT_HOSTSIZE,
+			 entry[n].ll.ll_host, UT_HOSTSIZE);
+    }
+
+  /* Check with an non present uid.  */
+  {
+    struct lastlog ll;
+    TEST_COMPARE (lastlog_read (filename, 4000, &ll), 0);
+  }
+}
+
+static int
+do_test (void)
+{
+  /* The path triggers the read/write of compat (32-bit ll_time) entries.  */
+  run_test ("/var/run/lastlog");
+
+  /* Any other file handles new (64-bit ll_time) entries.  */
+  run_test ("/var/run/lastlog.v2");
+
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/login/tst-lastlog.root/tst-lastlog.script b/login/tst-lastlog.root/tst-lastlog.script
new file mode 100644
index 0000000000..ca34ce7021
--- /dev/null
+++ b/login/tst-lastlog.root/tst-lastlog.script
@@ -0,0 +1,6 @@
+mkdirp 0755 /var/run
+touch  0664 /var/run/lastlog
+touch  0664 /var/run/lastlog.v2
+
+# Must run localedef as root to write into default paths.
+su
diff --git a/login/utmp.h b/login/utmp.h
index 7fc2d5cdf1..02a445ee82 100644
--- a/login/utmp.h
+++ b/login/utmp.h
@@ -91,6 +91,17 @@ extern int getutline_r (const struct utmp *__line,
 
 #endif	/* Use misc.  */
 
+#ifdef __USE_GNU
+/* Read the struct lastlog LL with UID from file FILE.  */
+extern ssize_t lastlog_read (const char *__file, uid_t __uid,
+			     struct lastlog *__ll)
+     __THROW __nonnull ((1, 3));
+/* Write the struct lastlog LL with UID from file FILE.  */
+extern ssize_t lastlog_write (const char *__file, uid_t __uid,
+			      const struct lastlog *__ll)
+     __THROW __nonnull ((1, 3));
+#endif
+
 __END_DECLS
 
 #endif /* utmp.h  */
diff --git a/sysdeps/generic/paths.h b/sysdeps/generic/paths.h
index ab2980e14a..9321ad7294 100644
--- a/sysdeps/generic/paths.h
+++ b/sysdeps/generic/paths.h
@@ -46,7 +46,8 @@
 #define	_PATH_DRUM	"/dev/drum"
 #define	_PATH_GSHADOW	"/etc/gshadow"
 #define	_PATH_KMEM	"/dev/kmem"
-#define	_PATH_LASTLOG	"/var/log/lastlog"
+#define _PATH_LASTLOG_VER ".v2"
+#define	_PATH_LASTLOG	"/var/log/lastlog" _PATH_LASTLOG_VER
 #define	_PATH_MAILDIR	"/var/mail"
 #define	_PATH_MAN	"/usr/share/man"
 #define	_PATH_MEM	"/dev/mem"
diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
index 77589e9aab..c21462d7c2 100644
--- a/sysdeps/mach/hurd/i386/libc.abilist
+++ b/sysdeps/mach/hurd/i386/libc.abilist
@@ -2214,6 +2214,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
index 5703811d47..6359fbe5d0 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
@@ -2182,6 +2182,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
index 556144b40a..d78825d9a3 100644
--- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
@@ -2264,6 +2264,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
index 3e01139bcc..eb5e302098 100644
--- a/sysdeps/unix/sysv/linux/arc/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
@@ -1942,6 +1942,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
index ffc3be5255..eb3e165ce8 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
@@ -166,6 +166,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
index cca9d7b2d8..2e7dbbe7df 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
@@ -163,6 +163,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
index b11eefe55e..fd4fb4a9a9 100644
--- a/sysdeps/unix/sysv/linux/csky/libc.abilist
+++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
@@ -2126,6 +2126,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
index f53f9d3dcc..8530ed550d 100644
--- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
@@ -2085,6 +2085,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
index 8604b9ba12..51b3d94801 100644
--- a/sysdeps/unix/sysv/linux/i386/libc.abilist
+++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
@@ -2252,6 +2252,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
index 75a8b98445..14299fa2aa 100644
--- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
@@ -2117,6 +2117,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
index e293d0e766..113d895744 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
@@ -167,6 +167,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
index ef071cd43f..b446ee38fd 100644
--- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
@@ -2197,6 +2197,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
index 7861c80ac2..b5b5ed8fea 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
@@ -2177,6 +2177,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
index c0aa1dd398..794cdb5069 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
@@ -2174,6 +2174,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
index 10b83a39e5..ab50ed5c78 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
@@ -2168,6 +2168,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
index 51cde431b8..e64ccb03b0 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
@@ -2166,6 +2166,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
index 5adbd9019e..688336b729 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
@@ -2174,6 +2174,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
index 9870c6d28a..91003c71e8 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
@@ -2168,6 +2168,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
index 49f615353b..522c733a27 100644
--- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
@@ -2215,6 +2215,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/paths.h b/sysdeps/unix/sysv/linux/paths.h
index 89686bcf88..b78dff7ae3 100644
--- a/sysdeps/unix/sysv/linux/paths.h
+++ b/sysdeps/unix/sysv/linux/paths.h
@@ -47,7 +47,8 @@
 #define	_PATH_GSHADOW	"/etc/gshadow"
 #define	_PATH_KLOG	"/proc/kmsg"
 #define	_PATH_KMEM	"/dev/kmem"
-#define	_PATH_LASTLOG	"/var/log/lastlog"
+#define _PATH_LASTLOG_VER ".v2"
+#define	_PATH_LASTLOG	"/var/log/lastlog" _PATH_LASTLOG_VER
 #define	_PATH_MAILDIR	"/var/mail"
 #define	_PATH_MAN	"/usr/share/man"
 #define	_PATH_MEM	"/dev/mem"
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
index b349bde439..99bc2a0df6 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
@@ -2224,6 +2224,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
index 43b2aabe84..156b336bfe 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
@@ -2257,6 +2257,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
index 7f02c58ee7..0b387f1b6b 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
@@ -2087,6 +2087,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
index 2da63c5a70..677435cf1a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
@@ -2377,6 +2377,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index 216e14cba2..537c5d61ad 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -1944,6 +1944,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index a34560861b..189a2ccf55 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2144,6 +2144,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/s390/lastlog-compat.h b/sysdeps/unix/sysv/linux/s390/lastlog-compat.h
new file mode 100644
index 0000000000..56fadc3b3b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/s390/lastlog-compat.h
@@ -0,0 +1,38 @@
+/* Compat lastlog definitions.  s390 definition.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _LASTLOG_COMPAT_H
+#define _LASTLOG_COMPAT_H 1
+
+/* The s390 changes its lastlog to 64-bit on glibc 2.9 without any handling
+   of old format.  The is_path_lastlog_compat assumes 64-bit as default.  */
+
+struct lastlog_compat
+{
+  int64_t ll_time;
+  char ll_line[UT_LINESIZE];
+  char ll_host[UT_HOSTSIZE];
+};
+
+static inline bool
+is_path_lastlog_compat (const char *file)
+{
+  return false;
+}
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
index a66426eb4d..00d9eba7cd 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
@@ -2211,6 +2211,8 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
index ab351873ae..b823639610 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
@@ -2112,6 +2112,8 @@ GLIBC_2.33 mknod F
 GLIBC_2.33 mknodat F
 GLIBC_2.33 stat F
 GLIBC_2.33 stat64 F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.4 _IO_fprintf F
 GLIBC_2.4 _IO_printf F
 GLIBC_2.4 _IO_sprintf F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
index b5b3b6c247..84d050ff2f 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
@@ -2092,6 +2092,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
index a0f1547fbf..da6cf58a8c 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
@@ -2089,6 +2089,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
index c76547d839..a678baade9 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
@@ -2213,6 +2213,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
index 75a0132c20..caaf400f53 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
@@ -2140,6 +2140,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
index 14bbd3450a..a3b5e44e00 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
@@ -2099,6 +2099,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
index 95b58039e0..e088e91ae2 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
@@ -2196,6 +2196,8 @@ GLIBC_2.34 getutmpx F
 GLIBC_2.34 getutxent F
 GLIBC_2.34 getutxid F
 GLIBC_2.34 getutxline F
+GLIBC_2.34 lastlog_read F
+GLIBC_2.34 lastlog_write F
 GLIBC_2.34 pututline F
 GLIBC_2.34 pututxline F
 GLIBC_2.34 updwtmp F


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-03-04 17:37 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-30 13:28 [glibc/azanella/y2038] login: Use 64-bit time on struct lastlog Adhemerval Zanella
2021-02-23 12:37 Adhemerval Zanella
2021-02-23 20:39 Adhemerval Zanella
2021-02-26 20:41 Adhemerval Zanella
2021-03-01 17:36 Adhemerval Zanella
2021-03-02 12:31 Adhemerval Zanella
2021-03-04 11:29 Adhemerval Zanella
2021-03-04 17:37 Adhemerval Zanella

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).