[22/52] login: Use 64-bit time on struct lastlog [BZ #25844]

Message ID 20210305201518.798584-23-adhemerval.zanella@linaro.org
State Superseded
Headers
Series Add 64 bit time support on legacy ABIs |

Commit Message

Adhemerval Zanella March 5, 2021, 8:14 p.m. UTC
  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.
---
 bits/types/struct_lastlog.h                   | 10 +--
 login/Makefile                                |  4 +-
 login/Versions                                |  2 +
 .../lastlog-compat.h                          | 25 +++---
 login/lastlog_read.c                          | 78 ++++++++++++++++++
 login/lastlog_write.c                         | 64 +++++++++++++++
 login/tst-lastlog.c                           | 80 +++++++++++++++++++
 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 +
 .../sysv/linux/m68k/coldfire/libc.abilist     |  2 +
 .../unix/sysv/linux/m68k/m680x0/libc.abilist  |  2 +
 .../sysv/linux/microblaze/be/libc.abilist     |  2 +
 .../sysv/linux/microblaze/le/libc.abilist     |  2 +
 .../sysv/linux/mips/mips32/fpu/libc.abilist   |  2 +
 .../sysv/linux/mips/mips32/nofpu/libc.abilist |  2 +
 .../sysv/linux/mips/mips64/n32/libc.abilist   |  2 +
 .../sysv/linux/mips/mips64/n64/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/nios2/libc.abilist    |  2 +
 sysdeps/unix/sysv/linux/paths.h               |  3 +-
 .../linux/powerpc/powerpc32/fpu/libc.abilist  |  2 +
 .../powerpc/powerpc32/nofpu/libc.abilist      |  2 +
 .../linux/powerpc/powerpc64/be/libc.abilist   |  2 +
 .../linux/powerpc/powerpc64/le/libc.abilist   |  2 +
 .../unix/sysv/linux/riscv/rv32/libc.abilist   |  2 +
 .../unix/sysv/linux/riscv/rv64/libc.abilist   |  2 +
 sysdeps/unix/sysv/linux/s390/lastlog-compat.h | 38 +++++++++
 .../unix/sysv/linux/s390/s390-32/libc.abilist |  2 +
 .../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 +
 .../sysv/linux/sparc/sparc32/libc.abilist     |  2 +
 .../sysv/linux/sparc/sparc64/libc.abilist     |  2 +
 .../unix/sysv/linux/x86_64/64/libc.abilist    |  2 +
 .../unix/sysv/linux/x86_64/x32/libc.abilist   |  2 +
 45 files changed, 369 insertions(+), 21 deletions(-)
 rename sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h => login/lastlog-compat.h (77%)
 create mode 100644 login/lastlog_read.c
 create mode 100644 login/lastlog_write.c
 create mode 100644 login/tst-lastlog.c
 create mode 100644 login/tst-lastlog.root/tst-lastlog.script
 create mode 100644 sysdeps/unix/sysv/linux/s390/lastlog-compat.h
  

Comments

Joseph Myers March 6, 2021, 12:07 a.m. UTC | #1
On Fri, 5 Mar 2021, Adhemerval Zanella via Libc-alpha wrote:

> 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.

I'd expect a NEWS entry, whether in this patch or another one, that goes 
into detail about how the different formats are handled for all affected 
files using the utmp and lastlog formats (so giving sufficient information 
for a distributor to implement upgrade support that avoids corrupting the 
files or losing any existing data in them, for example, and for anyone who 
wishes to write applications that access old files in the old formats).
  
Adhemerval Zanella March 8, 2021, 1:05 p.m. UTC | #2
On 05/03/2021 21:07, Joseph Myers wrote:
> On Fri, 5 Mar 2021, Adhemerval Zanella via Libc-alpha wrote:
> 
>> 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.
> 
> I'd expect a NEWS entry, whether in this patch or another one, that goes 
> into detail about how the different formats are handled for all affected 
> files using the utmp and lastlog formats (so giving sufficient information 
> for a distributor to implement upgrade support that avoids corrupting the 
> files or losing any existing data in them, for example, and for anyone who 
> wishes to write applications that access old files in the old formats).
> 

Fair enough, I will update the patch with a proper NEWS entry.
  

Patch

diff --git a/bits/types/struct_lastlog.h b/bits/types/struct_lastlog.h
index bde4dd2ad0..d267a24b1b 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 794d061604..7d273d95bc 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)"'
 
@@ -53,6 +54,7 @@  ifeq ($(have-GLIBC_2.33),yes)
 tests-container-internal := tst-utmp32
 tests-container := tst-utmp-default
 endif
+tests-container += 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 77%
rename from sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h
rename to login/lastlog-compat.h
index 4faa9922f4..00403dd19a 100644
--- a/sysdeps/unix/sysv/linux/s390/bits/struct_lastlog.h
+++ b/login/lastlog-compat.h
@@ -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..9880afdf00
--- /dev/null
+++ b/login/lastlog_read.c
@@ -0,0 +1,78 @@ 
+/* Read a lastlog entry.
+   Copyright (C) 2021 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>
+#include <shlib-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;
+  void *data;
+
+#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_33)
+  struct lastlog_compat llcompat;
+  if (is_path_lastlog_compat (file))
+    {
+      llsize = sizeof (struct lastlog_compat);
+      data = &llcompat;
+    }
+  else
+#endif
+    {
+      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 SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_33)
+  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);
+    }
+#endif
+
+  if (r == llsize)
+    {
+#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_33)
+      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);
+	}
+#endif
+      /* 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..37bad677d0
--- /dev/null
+++ b/login/lastlog_write.c
@@ -0,0 +1,64 @@ 
+/* Write a lastlog entry.
+   Copyright (C) 2021 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>
+#include <shlib-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;
+  const void *data;
+
+#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_33)
+  struct lastlog_compat llcompat;
+  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
+#endif
+    {
+      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 SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_33)
+  if (r == llsize && data == &llcompat)
+    r = sizeof (struct lastlog);
+#endif
+
+  return r;
+}
diff --git a/login/tst-lastlog.c b/login/tst-lastlog.c
new file mode 100644
index 0000000000..f36602df3e
--- /dev/null
+++ b/login/tst-lastlog.c
@@ -0,0 +1,80 @@ 
+/* Tests for lastlog read/write functions.
+   Copyright (C) 2021 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
+     for ABI that used to support it.  */
+  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