bug#64937: "who" reports funny dates

2023-08-10 Thread Thorsten Kukuk via GNU coreutils Bug Reports
On Thu, Aug 10, Bruno Haible wrote:

> This is merely a warning, and it's already gone after today's refactorings
> in Gnulib. To get past it, either remove '-Werror' from the Makefile, or
> bootstrap against the current Gnulib:

Thanks, I know how to get past it, else I couldn't have tested the result ;)
I only wanted to make aware of it, so that it does not go lost, since this 
warning doesn't happen in all configurations.

  Thorsten

-- 
Thorsten Kukuk, Distinguished Engineer, Senior Architect, Future Technologies
SUSE Software Solutions Germany GmbH, Frankenstraße 146, 90461 Nuernberg, 
Germany
Managing Director: Ivo Totev, Andrew McDonald, Werner Knoblich
(HRB 36809, AG Nürnberg)





bug#64937: "who" reports funny dates

2023-08-10 Thread Bruno Haible
Thorsten Kukuk wrote:
> Not sure how relevant this code still is, but currently I get with this:
> 
> lib/readutmp.c: In function 'get_boot_time_uncached':
> lib/readutmp.c:326:35: error: declaration of 'up' shadows a previous local 
> [-Werror=shadow]
>   326 |   struct timespec up =
>   |   ^~
> lib/readutmp.c:286:19: note: shadowed declaration is here
>   286 |   struct timespec up;
>   |   ^~
> cc1: all warnings being treated as errors

This is merely a warning, and it's already gone after today's refactorings
in Gnulib. To get past it, either remove '-Werror' from the Makefile, or
bootstrap against the current Gnulib:
  $ GNULIB_SRCDIR=
  $ ./bootstrap --no-git --gnulib-srcdir=$GNULIB_SRCDIR

Bruno








bug#64937: "who" reports funny dates

2023-08-10 Thread Thorsten Kukuk via GNU coreutils Bug Reports


Hi,

currently testing current coreutils git checkout on a utmp/wtmp free
machine, looks good so far. Except there is a compile problem with this
patch:

On Tue, Aug 08, Bruno Haible wrote:

> 2023-08-08  Bruno Haible  
> 
>   readutmp: Get the boot time with higher precision.
>   Suggested by Thorsten Kukuk  in
>   
> .
>   * lib/readutmp.c (get_boot_time_uncached): Try clock_gettime first.
> 
> diff --git a/lib/readutmp.c b/lib/readutmp.c
> index 7ef5bfe84c..f7e43eb4a6 100644
> --- a/lib/readutmp.c
> +++ b/lib/readutmp.c
> @@ -284,6 +284,31 @@ finish_utmp (struct utmp_alloc a)
>  static struct timespec
>  get_boot_time_uncached (void)
>  {
> +  /* The clock_gettime facility returns the uptime with a resolution of 1 
> µsec.
> + It is available with glibc >= 2.14.  In glibc < 2.17 it required linking
> + with librt.  */
> +#  if __GLIBC__ + (__GLIBC_MINOR__ >= 17) > 2
> +  struct timespec up;

Not sure how relevant this code still is, but currently I get with this:

lib/readutmp.c: In function 'get_boot_time_uncached':
lib/readutmp.c:326:35: error: declaration of 'up' shadows a previous local 
[-Werror=shadow]
  326 |   struct timespec up =
  |   ^~
lib/readutmp.c:286:19: note: shadowed declaration is here
  286 |   struct timespec up;
  |   ^~
cc1: all warnings being treated as errors


  Thorsten

-- 
Thorsten Kukuk, Distinguished Engineer, Senior Architect, Future Technologies
SUSE Software Solutions Germany GmbH, Frankenstraße 146, 90461 Nuernberg, 
Germany
Managing Director: Ivo Totev, Andrew McDonald, Werner Knoblich
(HRB 36809, AG Nürnberg)





bug#64937: "who" reports funny dates

2023-08-08 Thread Paul Eggert
Thanks, I installed the attached to simplify a bit further. A nice 
consequence of these recent changes is that we get to remove some pragmas.


The first patch is for Gnulib; the other two are for Coreutils.From e14d7e198f96039dbc4fb2118739e6ca1fc4cec6 Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Tue, 8 Aug 2023 19:29:55 -0700
Subject: [PATCH] readutmp: omit pragma
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* lib/readutmp.c: Omit -Sstringop-overread pragma.
It’s no longer needed now that extract_trimmed_name
no longer calls strnlen.
---
 ChangeLog  | 7 +++
 lib/readutmp.c | 5 -
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 199c818c18..40274c0a08 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2023-08-08  Paul Eggert  
+
+	readutmp: omit pragma
+	* lib/readutmp.c: Omit -Sstringop-overread pragma.
+	It’s no longer needed now that extract_trimmed_name
+	no longer calls strnlen.
+
 2023-08-08  Bruno Haible  
 
 	readutmp: Use classical implementation for files != /var/run/utmp.
diff --git a/lib/readutmp.c b/lib/readutmp.c
index 66b25bc7ae..31db4023a1 100644
--- a/lib/readutmp.c
+++ b/lib/readutmp.c
@@ -136,11 +136,6 @@
 # pragma GCC diagnostic ignored "-Wsizeof-pointer-memaccess"
 #endif
 
-/* Work around .  */
-#if 11 <= __GNUC__
-# pragma GCC diagnostic ignored "-Wstringop-overread"
-#endif
-
 /* Copy UT->ut_user into storage obtained from malloc.  Then remove any
trailing spaces from the copy, NUL terminate it, and return the copy.  */
 
-- 
2.39.2

From 422dcd424ca6b5fbef8d3bd0088e8e9e3757a203 Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Tue, 8 Aug 2023 19:32:49 -0700
Subject: [PATCH 1/2] pinky,who: omit pragma

* src/pinky.c, src/who.c:
Omit no-longer-needed -Wstringop-overread pragma.
---
 src/pinky.c | 6 --
 src/who.c   | 6 --
 2 files changed, 12 deletions(-)

diff --git a/src/pinky.c b/src/pinky.c
index 1429dd073..59c552bf1 100644
--- a/src/pinky.c
+++ b/src/pinky.c
@@ -426,12 +426,6 @@ print_heading (void)
   putchar ('\n');
 }
 
-/* Work around ,
-   triggered by STREQ_LEN with a negative length.  */
-#if 11 <= __GNUC__
-# pragma GCC diagnostic ignored "-Wstringop-overread"
-#endif
-
 /* Display UTMP_BUF, which should have N entries. */
 
 static void
diff --git a/src/who.c b/src/who.c
index 27a7904e1..074d2d5ad 100644
--- a/src/who.c
+++ b/src/who.c
@@ -570,12 +570,6 @@ print_heading (void)
   _("PID"), _("COMMENT"), _("EXIT"));
 }
 
-/* Work around ,
-   triggered by STREQ_LEN with a negative length.  */
-#if 11 <= __GNUC__
-# pragma GCC diagnostic ignored "-Wstringop-overread"
-#endif
-
 /* Display UTMP_BUF, which should have N entries. */
 static void
 scan_entries (idx_t n, const STRUCT_UTMP *utmp_buf)
-- 
2.39.2

From ad823360267cbfb3f5b1b3e1438122e5c82eb0b2 Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Tue, 8 Aug 2023 20:03:40 -0700
Subject: [PATCH 2/2] who: simplify based on readutmp changes

* src/pinky.c (time_string, print_entry, scan_entries, short_pinky):
* src/uptime.c (print_uptime, uptime):
* src/users.c (list_entries_users, users):
* src/who.c (UT_TYPE_RUN_LVL, UT_TYPE_INIT_PROCESS)
(UT_TYPE_LOGIN_PROCESS, UT_TYPE_DEAD_PROCESS, UT_TYPE_NEW_TIME)
(time_string, print_user, print_boottime)
(make_id_equals_comment, print_deadprocs, print_login)
(print_initspawn, print_clockchange, print_runlevel)
(list_entries_who, scan_entries, who):
Simplify, partly by using plain -> rather than macros.
---
 src/pinky.c  | 33 ++-
 src/uptime.c |  7 +++---
 src/users.c  |  5 ++---
 src/who.c| 63 ++--
 4 files changed, 44 insertions(+), 64 deletions(-)

diff --git a/src/pinky.c b/src/pinky.c
index 59c552bf1..5ad05e553 100644
--- a/src/pinky.c
+++ b/src/pinky.c
@@ -172,18 +172,10 @@ idle_string (time_t when)
 
 /* Return a time string.  */
 static char const *
-time_string (const STRUCT_UTMP *utmp_ent)
+time_string (struct gl_utmp const *utmp_ent)
 {
   static char buf[INT_STRLEN_BOUND (intmax_t) + sizeof "-%m-%d %H:%M"];
-
-  /* Don't take the address of UT_TIME_MEMBER directly.
- Ulrich Drepper wrote:
- "... GNU libc (and perhaps other libcs as well) have extended
- utmp file formats which do not use a simple time_t ut_time field.
- In glibc, ut_time is a macro which selects for backward compatibility
- the tv_sec member of a struct timeval value."  */
-  time_t t = UT_TIME_MEMBER (utmp_ent);
-  struct tm *tmp = localtime ();
+  struct tm *tmp = localtime (_ent->ut_ts.tv_sec);
 
   if (tmp)
 {
@@ -191,13 +183,13 @@ time_string (const STRUCT_UTMP *utmp_ent)
   return buf;
 }
   else
-return timetostr (t, buf);
+return timetostr (utmp_ent->ut_ts.tv_sec, buf);
 }
 
 /* Display a line 

bug#64937: "who" reports funny dates

2023-08-08 Thread Paul Eggert

On 2023-08-08 05:24, Thorsten Kukuk wrote:


Something emacs needs to get fixed. On musl libc systems like Alpine,
you don't have utmp nor wtmp.


Yes, as Bruno mentioned, we know of no way to find the boot time on 
Alpine. When Emacs cannot determine the boot time, it pretends that the 
system booted in 1970.




Beside that the emacs heuristic to find backups of wmtp is very
questionable, it wouldn't match on any of my systems.


It should work on our department's old Solaris 10 system, which has 
files /var/adm/wtmpx, /var/adm/wtmpx.0, /var/adm/wtmpx.1, ..., 
/var/adm/wtmpx.9, each about a week older than its predecessor.




There are better ways to determine the boot time.


If we could find these better ways, we could add them to Emacs etc. In 
the meantime I'm not sure what we can do. As Bruno mentioned, 
CLOCK_BOOTTIME doesn't work either. This area is a bit of a mess.




Does they really maintain btmp or is it just openssh, where you cannot
disable btmp entries?


Ubuntu 23.04 really maintains btmp. I just now deliberately used the 
wrong password on a console, and an entry was created in btmp.




I know that Fedora tries to maintain it via pam_lastlog.so, but do to
all the problems with this interface that module is deprecated and will
be removed in a future release.


Perhaps they'll remove it in 2038. :-) In the meantime, we still need a 
substitute for utmp, wtmp, and btmp.







bug#64937: "who" reports funny dates

2023-08-08 Thread Bruno Haible
I wrote:
> >  (2) The readutmp module should use a runtime 'if' rather than a 
> > compile-time
> >  #if, in order to dispatch between the systemd backend and the 
> > file-based
> >  backend.

This patch implements it.


2023-08-08  Bruno Haible  

readutmp: Use classical implementation for files != /var/run/utmp.
* lib/readutmp.c (read_utmp_from_systemd): Renamed from read_utmp
[READUTMP_USE_SYSTEMD]. Remove file argument.
(read_utmp): Call it when the file argument is "/var/run/utmp".

diff --git a/lib/readutmp.c b/lib/readutmp.c
index f7e43eb4a6..66b25bc7ae 100644
--- a/lib/readutmp.c
+++ b/lib/readutmp.c
@@ -439,17 +439,9 @@ guess_pty_name (uid_t uid, const struct timespec at)
   return NULL;
 }
 
-int
-read_utmp (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
-   int options)
+static int
+read_utmp_from_systemd (idx_t *n_entries, STRUCT_UTMP **utmp_buf, int options)
 {
-  /* The current implementation can imitate only UTMP_FILE.  */
-  if (strcmp (file, UTMP_FILE) != 0)
-{
-  errno = ENOTSUP;
-  return -1;
-}
-
   /* Fill entries, simulating what a utmp file would contain.  */
   struct utmp_alloc a = {0};
 
@@ -602,7 +594,9 @@ read_utmp (char const *file, idx_t *n_entries, STRUCT_UTMP 
**utmp_buf,
   return 0;
 }
 
-# elif defined UTMP_NAME_FUNCTION /* glibc, musl, macOS, FreeBSD, NetBSD, 
Minix, AIX, IRIX, Solaris, Cygwin, Android */
+# endif
+
+# if defined UTMP_NAME_FUNCTION /* glibc, musl, macOS, FreeBSD, NetBSD, Minix, 
AIX, IRIX, Solaris, Cygwin, Android */
 
 #  if !HAVE_UTMPX_H && HAVE_UTMP_H && !HAVE_DECL_GETUTENT
 struct utmp *getutent (void);
@@ -612,6 +606,12 @@ int
 read_utmp (char const *file, idx_t *n_entries, STRUCT_UTMP **utmp_buf,
int options)
 {
+#  if READUTMP_USE_SYSTEMD
+  if (strcmp (file, UTMP_FILE) == 0)
+/* Imitate reading UTMP_FILE, using systemd and Linux APIs.  */
+return read_utmp_from_systemd (n_entries, utmp_buf, options);
+#  endif
+
   /* Ignore the return value for now.
  Solaris' utmpname returns 1 upon success -- which is contrary
  to what the GNU libc version does.  In addition, older GNU libc








bug#64937: "who" reports funny dates

2023-08-08 Thread Bruno Haible
Thorsten Kukuk wrote:
> > What API do you suggest we use instead?
> 
> For me clock_gettime works very well:
> https://github.com/thkukuk/utmpx/blob/main/utmp-to-logind.md#determine-boot-time

Indeed, this provides the boot time with a resolution of 1 µsec. Whereas the
/proc/uptime approach only has a resolution of 1 µsec. Thanks for the
suggestion.


2023-08-08  Bruno Haible  

readutmp: Get the boot time with higher precision.
Suggested by Thorsten Kukuk  in

.
* lib/readutmp.c (get_boot_time_uncached): Try clock_gettime first.

diff --git a/lib/readutmp.c b/lib/readutmp.c
index 7ef5bfe84c..f7e43eb4a6 100644
--- a/lib/readutmp.c
+++ b/lib/readutmp.c
@@ -284,6 +284,31 @@ finish_utmp (struct utmp_alloc a)
 static struct timespec
 get_boot_time_uncached (void)
 {
+  /* The clock_gettime facility returns the uptime with a resolution of 1 µsec.
+ It is available with glibc >= 2.14.  In glibc < 2.17 it required linking
+ with librt.  */
+#  if __GLIBC__ + (__GLIBC_MINOR__ >= 17) > 2
+  struct timespec up;
+  if (clock_gettime (CLOCK_BOOTTIME, ) >= 0)
+{
+  struct timespec result;
+  /* equivalent to:
+  if (clock_gettime (CLOCK_REALTIME, ) >= 0)
+  */
+  if (timespec_get (, TIME_UTC) >= 0)
+{
+  if (result.tv_nsec < up.tv_nsec)
+{
+  result.tv_nsec += 10;
+  result.tv_sec -= 1;
+}
+  result.tv_sec -= up.tv_sec;
+  result.tv_nsec -= up.tv_nsec;
+  return result;
+}
+}
+#  endif
+
   /* /proc/uptime contains the uptime with a resolution of 0.01 sec.  */
   FILE *fp = fopen ("/proc/uptime", "re");
   if (fp != NULL)








bug#64937: "who" reports funny dates

2023-08-08 Thread Thorsten Kukuk via GNU coreutils Bug Reports
On Tue, Aug 08, Robert Pluim wrote:

> > On Tue, 8 Aug 2023 14:29:27 +, Thorsten Kukuk  said:
> Thorsten> Which means tools like who just don't show anything. And emacs 
> will
> Thorsten> never find out the boot time with the current code.
> 
> What API do you suggest we use instead?

For me clock_gettime works very well:
https://github.com/thkukuk/utmpx/blob/main/utmp-to-logind.md#determine-boot-time

  Thorsten


-- 
Thorsten Kukuk, Distinguished Engineer, Senior Architect, Future Technologies
SUSE Software Solutions Germany GmbH, Frankenstraße 146, 90461 Nuernberg, 
Germany
Managing Director: Ivo Totev, Andrew McDonald, Werner Knoblich
(HRB 36809, AG Nürnberg)





bug#64937: "who" reports funny dates

2023-08-08 Thread Bruno Haible
I wrote:
> >  (1) The API of the readutmp module should provide unlimited-length 
> > ut_user,
> >  ut_host etc. fields always. No more #ifdef UT_USER_SIZE.
> >  (2) The readutmp module should use a runtime 'if' rather than a 
> > compile-time
> >  #if, in order to dispatch between the systemd backend and the 
> > file-based
> >  backend.
> > 
> >  I'll work on (1) today.

(1) done through the following patch.

It does not break coreutils. But coreutils can now be simplified through the
attached 0001-maint-Simplify-after-gnulib-changed.patch .


2023-08-08  Bruno Haible  

readutmp: Return entries with unbounded strings on all platforms.
Suggested  by Paul Eggert in
.
* m4/readutmp.m4 (gl_READUTMP): Test also whether struct utmp has an
ut_tv member, and whether struct utmp and struct utmpx have an
ut_session member.
* lib/readutmp.h (struct gl_utmp): Define always. Add ut_exit field.
(HAVE_GL_UTMP): Remove macro.
(UT_USER, UT_TIME_MEMBER, UT_PID, UT_TYPE_EQ, UT_TYPE_NOT_DEFINED,
UT_EXIT_E_TERMINATION, UT_EXIT_E_EXIT, STRUCT_UTMP): Define w.r.t.
struct gl_utmp.
(UT_USER_SIZE, UT_ID_SIZE, UT_LINE_SIZE, UT_HOST_SIZE): Define to -1
always.
(getutent): Remove declaration.
(HAVE_STRUCT_XTMP_UT_EXIT): Remove unused macro.
(HAVE_STRUCT_XTMP_UT_ID, HAVE_STRUCT_XTMP_UT_PID,
HAVE_STRUCT_XTMP_UT_HOST): Change to match the way coreutils uses these
macros.
* lib/readutmp.c (UT_USER, UT_TIME_MEMBER, UT_PID, UT_TYPE_EQ,
UT_TYPE_NOT_DEFINED, IS_USER_PROCESS, UT_EXIT_E_TERMINATION,
UT_EXIT_E_EXIT, UT_USER_SIZE, UT_ID_SIZE, UT_LINE_SIZE, UT_HOST_SIZE):
Define w.r.t. struct utmpx or struct utmp.
(extract_trimmed_name): Don't use UT_USER or UT_USER_SIZE here.
(desirable_utmp_entry): Don't use UT_TIME_MEMBER or UT_USER here.
(struct utmp_alloc): Define always.
(add_utmp): Likewise. Add user_len, id_len, line_len, host_len,
termination, exit arguments. Don't require that user, id, line, host are
NUL-terminated. Assume user and host are non-NULL.
(finish_utmp): New function, extracted from read_utmp.
(read_utmp) [READUTMP_USE_SYSTEMD]: Update add_utmp invocations. Pass a
non-NULL user and a non-NULL host. Call finish_utmp.
(getutent): Move declaration from readutmp.h to here.
(copy_utmp_entry): Remove function.
(read_utmp) [UTMP_NAME_FUNCTION]: Replace variables n_read, n_alloc,
utmp with a 'struct utmp_alloc'. Use 'struct utmpx32' from
copy_utmp_entry here. Invoke add_utmp and finish_utmp.
(read_utmp) [!UTMP_NAME_FUNCTION]: Replace variables n_read, n_alloc,
utmp with a 'struct utmp_alloc'. Invoke add_utmp and finish_utmp.
* NEWS: Mention the API change.

From 622d2c0763777eb909a4fda5048238f524cc36f9 Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Tue, 8 Aug 2023 17:36:10 +0200
Subject: [PATCH] readutmp: Return entries with unbounded strings on all
 platforms.

Suggested  by Paul Eggert in
.

* m4/readutmp.m4 (gl_READUTMP): Test also whether struct utmp has an
ut_tv member, and whether struct utmp and struct utmpx have an
ut_session member.
* lib/readutmp.h (struct gl_utmp): Define always. Add ut_exit field.
(HAVE_GL_UTMP): Remove macro.
(UT_USER, UT_TIME_MEMBER, UT_PID, UT_TYPE_EQ, UT_TYPE_NOT_DEFINED,
UT_EXIT_E_TERMINATION, UT_EXIT_E_EXIT, STRUCT_UTMP): Define w.r.t.
struct gl_utmp.
(UT_USER_SIZE, UT_ID_SIZE, UT_LINE_SIZE, UT_HOST_SIZE): Define to -1
always.
(getutent): Remove declaration.
(HAVE_STRUCT_XTMP_UT_EXIT): Remove unused macro.
(HAVE_STRUCT_XTMP_UT_ID, HAVE_STRUCT_XTMP_UT_PID,
HAVE_STRUCT_XTMP_UT_HOST): Change to match the way coreutils uses these
macros.
* lib/readutmp.c (UT_USER, UT_TIME_MEMBER, UT_PID, UT_TYPE_EQ,
UT_TYPE_NOT_DEFINED, IS_USER_PROCESS, UT_EXIT_E_TERMINATION,
UT_EXIT_E_EXIT, UT_USER_SIZE, UT_ID_SIZE, UT_LINE_SIZE, UT_HOST_SIZE):
Define w.r.t. struct utmpx or struct utmp.
(extract_trimmed_name): Don't use UT_USER or UT_USER_SIZE here.
(desirable_utmp_entry): Don't use UT_TIME_MEMBER or UT_USER here.
(struct utmp_alloc): Define always.
(add_utmp): Likewise. Add user_len, id_len, line_len, host_len,
termination, exit arguments. Don't require that user, id, line, host are
NUL-terminated. Assume user and host are non-NULL.
(finish_utmp): New function, extracted from read_utmp.
(read_utmp) [READUTMP_USE_SYSTEMD]: Update add_utmp invocations. Pass a
non-NULL user and a non-NULL host. Call finish_utmp.
(getutent): Move declaration from readutmp.h to here.
(copy_utmp_entry): Remove function.
(read_utmp) [UTMP_NAME_FUNCTION]: Replace variables n_read, n_alloc,
utmp with a 'struct utmp_alloc'. Use 'struct utmpx32' from

bug#64937: "who" reports funny dates

2023-08-08 Thread Robert Pluim
> On Tue, 08 Aug 2023 18:11:20 +0200, Bruno Haible  said:

Bruno> Robert Pluim wrote:
Thorsten> They don't record at all.
Thorsten> Which means tools like who just don't show anything. And emacs 
will
Thorsten> never find out the boot time with the current code.
>> 
>> What API do you suggest we use instead?

Bruno> musl libc runs only on Linux. On Linux, you can use this approach 
from Gnulib:
Bruno> 
https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=lib/readutmp.c;h=4e1d7ec26bef6cba4474433f72c9079b61794b97;hb=HEAD#l96
Bruno> lines 96..150.

So either reading "/proc/uptime" or calling "sysinfo". Iʼm assuming
the former is just the latter written to a file as a string, which we
can then parse again and turn into an integer. How efficient :-)

Bruno> Part of it may already be contained in emacs/src/filelock.c; I can't 
tell.

No, that currently uses either sysctl (probably only on *BSD and
macOS) or utmp/wtmp.

Robert
-- 





bug#64937: "who" reports funny dates

2023-08-08 Thread Bruno Haible
Robert Pluim wrote:
> Thorsten> They don't record at all.
> Thorsten> Which means tools like who just don't show anything. And emacs 
> will
> Thorsten> never find out the boot time with the current code.
> 
> What API do you suggest we use instead?

musl libc runs only on Linux. On Linux, you can use this approach from Gnulib:
https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=lib/readutmp.c;h=4e1d7ec26bef6cba4474433f72c9079b61794b97;hb=HEAD#l96
lines 96..150.

Part of it may already be contained in emacs/src/filelock.c; I can't tell.

Bruno








bug#64937: "who" reports funny dates

2023-08-08 Thread Bruno Haible
Paul Eggert wrote:
> 0006-readutmp-switch-new-struct-to-struct-timespec.patch

> @@ -150,12 +150,11 @@ struct gl_utmp
> ⎣ ut_addr_v6   [u]int[4]  glibc, musl, Android
>   */
>  
> -# include 
>  # if !HAVE_DECL_GETUTENT
>  struct utmp *getutent (void);
>  # endif
>  # define UTMP_STRUCT_NAME utmp
> -# define UT_TIME_MEMBER(UT) ((UT)->ut_time)
> +# define UT_TIME_MEMBER(UT) ((UT)->ut_ts.tv_sec)
>  # define SET_UTMP_ENT setutent
>  # define GET_UTMP_ENT getutent
>  # define END_UTMP_ENT endutent

This causes a compilation error on OpenBSD, AIX, and Android:

On OpenBSD:
../../gllib/readutmp.c:76:20: error: no member named 'ut_ts' in 'struct utmp'
  bool user_proc = IS_USER_PROCESS (ut);
   ^~~~
../../gllib/readutmp.h:297:36: note: expanded from macro 'IS_USER_PROCESS'
|| (UT_TYPE_NOT_DEFINED && UT_TIME_MEMBER (UT) != 0)))
   ^~~
../../gllib/readutmp.h:158:36: note: expanded from macro 'UT_TIME_MEMBER'
# define UT_TIME_MEMBER(UT) ((UT)->ut_ts.tv_sec)
   ^

On AIX:

"../../gllib/readutmp.c", line 76.20: 1506-022 (S) "ut_ts" is not a member of 
"const struct utmp".
make: 1254-004 The error code from the last command is 1.

On Android:
../../gllib/readutmp.c:76:20: error: no member named 'ut_ts' in 'struct utmp'; 
did you mean 'ut_tv'?


This patch fixes it.


2023-08-08  Bruno Haible  

readutmp: Fix compilation error on OpenBSD and AIX (regr. 2023-08-03).
* lib/readutmp.h (UT_TIME_MEMBER) [HAVE_UTMP_H]: Revert last change.

diff --git a/lib/readutmp.h b/lib/readutmp.h
index 9f53246597..043ae6df16 100644
--- a/lib/readutmp.h
+++ b/lib/readutmp.h
@@ -155,7 +155,7 @@ struct gl_utmp
 struct utmp *getutent (void);
 # endif
 # define UTMP_STRUCT_NAME utmp
-# define UT_TIME_MEMBER(UT) ((UT)->ut_ts.tv_sec)
+# define UT_TIME_MEMBER(UT) ((UT)->ut_time)
 # define SET_UTMP_ENT setutent
 # define GET_UTMP_ENT getutent
 # define END_UTMP_ENT endutent








bug#64937: "who" reports funny dates

2023-08-08 Thread Bruno Haible
I wrote on 2023-08-02:
> I wrote:
> > The proposed patch is attached.
> 
> Oops, I missed a sizeof of the ut_id field. A corrected patch is attached.

Oops, this causes a compilation error on OpenBSD:

In file included from ../../gllib/readutmp.c:22:
../../gllib/readutmp.h:216:50: error: no member named 'ut_id' in 'struct utmp'
enum { UT_ID_SIZE = sizeof (((STRUCT_UTMP *) 0)->ut_id) };
~~~  ^

This patch fixes it.


2023-08-08  Bruno Haible  

readutmp: Fix compilation error on OpenBSD (regr. 2023-08-02).
* lib/readutmp.h (UT_ID_SIZE): Define to a dummy if there is no ut_id
field.

diff --git a/lib/readutmp.h b/lib/readutmp.h
index 01964d2622..9f53246597 100644
--- a/lib/readutmp.h
+++ b/lib/readutmp.h
@@ -213,7 +213,11 @@ enum { UT_USER_SIZE = sizeof UT_USER ((STRUCT_UTMP *) 0) };
 #if HAVE_GL_UTMP
 enum { UT_ID_SIZE = -1 };
 #else
+# if (HAVE_UTMPX_H ? HAVE_STRUCT_UTMPX_UT_ID : HAVE_STRUCT_UTMP_UT_ID)
 enum { UT_ID_SIZE = sizeof (((STRUCT_UTMP *) 0)->ut_id) };
+# else
+enum { UT_ID_SIZE = 1 };
+# endif
 # define UT_ID_SIZE UT_ID_SIZE
 #endif
 








bug#64937: "who" reports funny dates

2023-08-08 Thread Robert Pluim
> On Tue, 8 Aug 2023 14:29:27 +, Thorsten Kukuk  said:

Thorsten> On Tue, Aug 08, Bruno Haible wrote:
>> Thorsten Kukuk wrote:
>> > On musl libc systems like Alpine,
>> > you don't have utmp nor wtmp.
>> 
>> But on Alpine Linux, I don't see a systemd nor a logind daemon.
>> How are logins meant to be recorded on this system?

Thorsten> They don't record at all.
Thorsten> Which means tools like who just don't show anything. And emacs 
will
Thorsten> never find out the boot time with the current code.

What API do you suggest we use instead?

Robert
-- 





bug#64937: "who" reports funny dates

2023-08-08 Thread Thorsten Kukuk via GNU coreutils Bug Reports
On Tue, Aug 08, Bruno Haible wrote:

> Thorsten Kukuk wrote:
> > On musl libc systems like Alpine,
> > you don't have utmp nor wtmp.
> 
> But on Alpine Linux, I don't see a systemd nor a logind daemon.
> How are logins meant to be recorded on this system?

They don't record at all.
Which means tools like who just don't show anything. And emacs will
never find out the boot time with the current code.

  Thorsten

-- 
Thorsten Kukuk, Distinguished Engineer, Senior Architect, Future Technologies
SUSE Software Solutions Germany GmbH, Frankenstraße 146, 90461 Nuernberg, 
Germany
Managing Director: Ivo Totev, Andrew McDonald, Werner Knoblich
(HRB 36809, AG Nürnberg)





bug#64937: "who" reports funny dates

2023-08-08 Thread Bruno Haible
Thorsten Kukuk wrote:
> On musl libc systems like Alpine,
> you don't have utmp nor wtmp.

But on Alpine Linux, I don't see a systemd nor a logind daemon.
How are logins meant to be recorded on this system?

Bruno








bug#64937: "who" reports funny dates

2023-08-08 Thread Thorsten Kukuk via GNU coreutils Bug Reports
On Mon, Aug 07, Paul Eggert wrote:

> On 2023-08-07 04:22, Bruno Haible wrote:
> 
> > sooner than later. My guess is that Fedora and Ubuntu/Debian are only
> > waiting for 'who' (coreutils) and 'last' (util-linux / wtmpdb) to
> > stop accessing these two files.
> 
> It's not just those two programs. Emacs looks at utmp, for example, when 
> creating the symlinks it uses to implement its own file locking, because 
>   symlink contents contain the boot time (so that Emacs can better 
> detect stale locks) and the boot time is retrieved from /var/run/utmp.

Something emacs needs to get fixed. On musl libc systems like Alpine,
you don't have utmp nor wtmp.
Beside that the emacs heuristic to find backups of wmtp is very
questionable, it wouldn't match on any of my systems.
There are better ways to determine the boot time.

> I expect that other programs look at utmp and/or wtmp, besides obvious 
> candidates like 'login'. A quick scan through my Ubuntu /usr/bin found 
> sessreg, for example; it was originally developed for X but is now used 
> elsewhere.

There are some few:
https://github.com/thkukuk/utmpx/blob/main/Y2038.md#depending-on-utmpwtmpbtmplastlog-directly
And yes, the list is incomplete.

But to be honest, the majority is only creating entries (no longer
necessary) or counting the number of logged in users.
Other don't work since a long time since nobody writes the entries they
are looking for (like e.g. adjtimex).

So it's not that worse as it looks first.

> >> Although Ubuntu does not maintain /var/log/btmp
> > 
> > What do you mean by that?
> 
> Oh, my mistake. I checked a workstation that was behind a restrictive 
> firewall, and nobody had ever attempted to attack it. You're right, 
> Ubuntu maintains btmp.

Does they really maintain btmp or is it just openssh, where you cannot
disable btmp entries?
In the last case, the file is pretty useless, as all failed logins via
other ways (e.g. login itself) are not logged.

I know that Fedora tries to maintain it via pam_lastlog.so, but do to
all the problems with this interface that module is deprecated and will
be removed in a future release.

  Thorsten

-- 
Thorsten Kukuk, Distinguished Engineer, Senior Architect, Future Technologies
SUSE Software Solutions Germany GmbH, Frankenstraße 146, 90461 Nuernberg, 
Germany
Managing Director: Ivo Totev, Andrew McDonald, Werner Knoblich
(HRB 36809, AG Nürnberg)





bug#64937: "who" reports funny dates

2023-08-07 Thread Paul Eggert

On 2023-08-07 04:22, Bruno Haible wrote:


Since the fact that /var/run/utmp and /var/log/wtmp are world-readable
implies that they are world-lockable and thus the DoS bug
https://sourceware.org/bugzilla/show_bug.cgi?id=24492 applies,
to me it's clear that both utmp and wtmp needs to go away


Although that bug should be fixed, a fix doesn't require utmp and wtmp 
to go away. It can instead be fixed as Davin McCall suggested in the 
original bug report, by making the files not world-lockable. This should 
be doable on GNU/Linux (and I expect on other platform that support 
these files) by implementing his suggestion. Admittedly the fix has been 
low priority, but that doesn't mean it's not doable.




sooner than later. My guess is that Fedora and Ubuntu/Debian are only
waiting for 'who' (coreutils) and 'last' (util-linux / wtmpdb) to
stop accessing these two files.


It's not just those two programs. Emacs looks at utmp, for example, when 
creating the symlinks it uses to implement its own file locking, because 
 symlink contents contain the boot time (so that Emacs can better 
detect stale locks) and the boot time is retrieved from /var/run/utmp.


I expect that other programs look at utmp and/or wtmp, besides obvious 
candidates like 'login'. A quick scan through my Ubuntu /usr/bin found 
sessreg, for example; it was originally developed for X but is now used 
elsewhere.


Of course a better scheme could be arranged than utmp/wtmp. The problem 
is that it has not been arranged yet and progress in this area has been 
slow.




Although Ubuntu does not maintain /var/log/btmp


What do you mean by that?


Oh, my mistake. I checked a workstation that was behind a restrictive 
firewall, and nobody had ever attempted to attack it. You're right, 
Ubuntu maintains btmp.




   * The /var/log/wtmp argument to "who" and "users" should become deprecated.


If it is deprecated, we'll need a significant overlap period where the 
system both maintains utmp/wtmp/btmp, and also supports an alternative 
system. Ideally applications won't notice the transition, at least if 
they're using the POSIX/glibc interfaces in .




   * Whereas for /var/log/btmp we need to make an effort to continue supporting
 it, in the same 'who' program that accesses the systemd API for utmp.
 And access the time stamp in it as an unsigned 32-bit integer, like
 Andreas Schwab proposed (already implemented).


Although going to unsigned 32-bit integers is an improvement, it stops 
working in the year 2106 unless we install further hacks later. Better 
would be to widen the ?tmp files time_t to 64 bits, as is done on most 
other 64-bit platforms. This would require a flag-day conversion during 
a software upgrade, but that's doable, and -based programs 
should work after the upgrade is done.



 This means:
 (1) The API of the readutmp module should provide unlimited-length ut_user,
 ut_host etc. fields always. No more #ifdef UT_USER_SIZE.
 (2) The readutmp module should use a runtime 'if' rather than a 
compile-time
 #if, in order to dispatch between the systemd backend and the 
file-based
 backend.

 I'll work on (1) today.


Thanks. Both ideas sound good to me for Gnulib.

One issue with (1) is that readutmp.h currently defines a boatload of 
macros like UT_USER_SIZE, UT_TIME_MEMBER and UT_EXIT_E_TERMINATION that 
aren't needed if every platform simply uses struct gl_utmp. It'd be 
simpler to remove those macros (or move them to readutmp.c). Although it 
is also tempting to leave those macros in readutmp.h for backward 
compatibility, that might be more trouble than it's worth, as readutmp.h 
is already incompatible with how it was a week ago.






bug#64937: "who" reports funny dates

2023-08-07 Thread Bruno Haible
Paul Eggert wrote:
> Fedora 38 runs 
> systemd, for example, and it still maintains /var/log/wtmp. Likewise for 
> Ubuntu 23.04.

Well, these are the permissions of these files:

   /var/run/utmp /var/log/wtmp  /var/log/btmpowner

Ubuntu 23.04   rw-rw-r-- rw-rw-r--  rw-rwroot:utmp
Debian 12  rw-rw-r-- rw-rw-r--  rw-rwroot:utmp
Fedora Rawhide rw-rw-r-- rw-rw-r--  rw-rwroot:utmp
  context  initrc_var_run_t  wtmp_t faillog_t
openSUSE 15.5  rw-rw-r-- rw-rw-r--  rw-rwroot:utmp
Slackware 14   rw-rw-r-- rw-rw-r--  rw---root:utmp, 
btmp only root:root
Alpine 3.18rw-rw-r-- rw-rw-r--  rw-rwroot:utmp
Debian Hurdrw-rw-r-- rw-rw-r--  rw-rwroot:utmp

Since the fact that /var/run/utmp and /var/log/wtmp are world-readable
implies that they are world-lockable and thus the DoS bug
https://sourceware.org/bugzilla/show_bug.cgi?id=24492 applies,
to me it's clear that both utmp and wtmp needs to go away rather
sooner than later. My guess is that Fedora and Ubuntu/Debian are only
waiting for 'who' (coreutils) and 'last' (util-linux / wtmpdb) to
stop accessing these two files.

> > Is there somebody really using btmp? Beside that it is really unreliable
> > since nearly no application is writing it, I asked on several mailing
> > lists and nobody answered.

I agree with Paul: When three books/blogs mention /var/log/btmp and the
ability to run "sudo who -a /var/log/btmp", and additionally a command
'lastb' exists, for "sudo lastb", we cannot ignore that.

> Although Ubuntu does not maintain /var/log/btmp

What do you mean by that? On Ubuntu 23.04, I just did a "ssh localhost"
with a wrong password, and then I see:

$ sudo who -a /var/log/btmp
LOGIN  ssh:notty2023-08-07 13:06  2564 id=
$ sudo lastb
brunossh:notty127.0.0.1   Mon Aug 7 13:06 - 13:06  (00:00)

Similarly when there were several failed logins.

("sudo who /var/log/btmp" prints nothing, because it filters out the LOGIN
lines. "who -a /var/log/btmp" prints nothing, because it cannot open the
file.)

So, IMO, the conclusion is:
  * The /var/log/wtmp argument to "who" and "users" should become deprecated.
  * Whereas for /var/log/btmp we need to make an effort to continue supporting
it, in the same 'who' program that accesses the systemd API for utmp.
And access the time stamp in it as an unsigned 32-bit integer, like
Andreas Schwab proposed (already implemented).
This means:
(1) The API of the readutmp module should provide unlimited-length ut_user,
ut_host etc. fields always. No more #ifdef UT_USER_SIZE.
(2) The readutmp module should use a runtime 'if' rather than a compile-time
#if, in order to dispatch between the systemd backend and the file-based
backend.

I'll work on (1) today.

Bruno








bug#64937: "who" reports funny dates

2023-08-06 Thread Paul Eggert

On 2023-08-06 14:06, Thorsten Kukuk wrote:


SysV Init is gone and the majority does not miss it, and I don't see a
reason why "who /var/log/wtmp" needs to stay.


I don't want to get into the middle of another systemd vs init battle. 
But I don't see why this is relevant to that battle. Fedora 38 runs 
systemd, for example, and it still maintains /var/log/wtmp. Likewise for 
Ubuntu 23.04.




Is there somebody really using btmp? Beside that it is really unreliable
since nearly no application is writing it, I asked on several mailing
lists and nobody answered.


Although Ubuntu does not maintain /var/log/btmp, Fedora does. I just 
tested my Fedora 38 workstation, and /var/log/btmp records failed logins 
back when I installed Fedora on it. Attackers on the Internet try to log 
in to this workstation via ssh every few minutes. Logs like btmp could 
be useful for forensics if an attack succeeds.






bug#64937: "who" reports funny dates

2023-08-06 Thread Paul Eggert

On 2023-08-06 14:10, Thorsten Kukuk wrote:

On Sun, Aug 06, Paul Eggert wrote:


On 2023-08-06 13:00, Paul Eggert wrote:


How does "last" emulate /var/log/wtmp using systemd?


Oh, I see from  that wtmpdb comes
with its own "last". Is the plan to migrate this code into util-linux
"last", or simply to kill off util-linux "last"?  Similarly for
util-linux utmpdmp,  procps "w", etc.


util-linux will merge lastlog2, I have no idea about wtmpdb, this wasn't
a topic yet before my vacation.


Does lastlog2 store only the last login of each user? If so, it won't 
work for a command like "last eggert", which outputs all the times that 
I've logged in since wtmp was rotated.




procps-ng kills reading files directly and will use systemd, patch got
accepted but not yet merged.
The current patches for util-linux do the same.
I haven't looked at the latest PR for shadow, but they planned the same.

So nobody seems to care about "backward compatibily" with a time
where tools like "last" did not yet exist.


Hmm, well I guess I care. (Call me an old-timer. :-) Admittedly I care 
more about usage like "last eggert".




Also, the question about /var/adm/btmp remains.


Is there a use-case, for which it is __reliable__ useable?


I don't know what you mean by __reliable__. Certainly there are commands 
that use /var/adm/btmp. util-linux's "lastb" command uses it, for 
example. Will lastb stop working?




Until now, nobody could tell me one and nobody cared.


Perhaps you're not talking to the right people? I can find a reasonable 
amount of discussion about this stuff. For example, even if we restrict 
our attention to btmp, a Google search using the query "lastb btmp" 
returned 68,200 results for me just now, with many results on 
serverfault.com, stackexchange.com, linuxhint.com, etc.






bug#64937: "who" reports funny dates

2023-08-06 Thread Thorsten Kukuk via GNU coreutils Bug Reports
On Sun, Aug 06, Paul Eggert wrote:

> On 2023-08-06 13:00, Paul Eggert wrote:
> 
> > How does "last" emulate /var/log/wtmp using systemd?
> 
> Oh, I see from  that wtmpdb comes 
> with its own "last". Is the plan to migrate this code into util-linux 
> "last", or simply to kill off util-linux "last"?  Similarly for 
> util-linux utmpdmp,  procps "w", etc.

util-linux will merge lastlog2, I have no idea about wtmpdb, this wasn't
a topic yet before my vacation.

procps-ng kills reading files directly and will use systemd, patch got
accepted but not yet merged.
The current patches for util-linux do the same.
I haven't looked at the latest PR for shadow, but they planned the same.

So nobody seems to care about "backward compatibily" with a time
where tools like "last" did not yet exist.

> Also, the question about /var/adm/btmp remains.

Is there a use-case, for which it is __reliable__ useable?

Until now, nobody could tell me one and nobody cared.

  Thorsten

-- 
Thorsten Kukuk, Distinguished Engineer, Senior Architect, Future Technologies
SUSE Software Solutions Germany GmbH, Frankenstraße 146, 90461 Nuernberg, 
Germany
Managing Director: Ivo Totev, Andrew McDonald, Werner Knoblich
(HRB 36809, AG Nürnberg)





bug#64937: "who" reports funny dates

2023-08-06 Thread Thorsten Kukuk via GNU coreutils Bug Reports
On Sun, Aug 06, Paul Eggert wrote:

> On 2023-08-03 23:53, Thorsten Kukuk wrote:
> > And yes, "who /var/log/wtmp" will not work with this, too. But is this
> > really a required or usefull use case?
> > /usr/bin/last can give you the same output.
> 
> Sure, but some people use "who" for that.[1][2][3] This is partly 
> because "who" predates "last".

Somebody wrote some weeks ago: only because there was a Unix system 
40 years ago nobody remembers anymore today with this limitations, there is
no reason for Linux to stick with this limitations.

SysV Init is gone and the majority does not miss it, and I don't see a 
reason why "who /var/log/wtmp" needs to stay.

> How does "last" emulate /var/log/wtmp using systemd?

No, systemd handles current sessions, no historic data.

> Also, what about /var/log/btmp? That is, what is the systemd substitute 
> for "who /var/log/btmp" or "last -f /var/log/btmp"?

Is there somebody really using btmp? Beside that it is really unreliable
since nearly no application is writing it, I asked on several mailing
lists and nobody answered.

  Thorsten

> [1]: https://linuxhandbook.com/who-command/
> [2]: https://linuxtldr.com/who-command/
> [3]: https://kamotora.net/system/linux/check-btmp-wtmp-utmp/

-- 
Thorsten Kukuk, Distinguished Engineer, Senior Architect, Future Technologies
SUSE Software Solutions Germany GmbH, Frankenstraße 146, 90461 Nuernberg, 
Germany
Managing Director: Ivo Totev, Andrew McDonald, Werner Knoblich
(HRB 36809, AG Nürnberg)





bug#64937: "who" reports funny dates

2023-08-06 Thread Paul Eggert

On 2023-08-06 13:00, Paul Eggert wrote:


How does "last" emulate /var/log/wtmp using systemd?


Oh, I see from  that wtmpdb comes 
with its own "last". Is the plan to migrate this code into util-linux 
"last", or simply to kill off util-linux "last"?  Similarly for 
util-linux utmpdmp,  procps "w", etc.


Also, the question about /var/adm/btmp remains.





bug#64937: "who" reports funny dates

2023-08-06 Thread Paul Eggert

On 2023-08-03 23:53, Thorsten Kukuk wrote:

And yes, "who /var/log/wtmp" will not work with this, too. But is this
really a required or usefull use case?
/usr/bin/last can give you the same output.


Sure, but some people use "who" for that.[1][2][3] This is partly 
because "who" predates "last".


How does "last" emulate /var/log/wtmp using systemd?

Also, what about /var/log/btmp? That is, what is the systemd substitute 
for "who /var/log/btmp" or "last -f /var/log/btmp"?


[1]: https://linuxhandbook.com/who-command/
[2]: https://linuxtldr.com/who-command/
[3]: https://kamotora.net/system/linux/check-btmp-wtmp-utmp/





bug#64937: "who" reports funny dates

2023-08-06 Thread Paul Eggert

On 2023-08-04 04:58, Bruno Haible wrote:

The mentioned GCC bug is about a -Wanalyzer-use-after-free false positive.
I guess you meanthttps://gcc.gnu.org/bugzilla/show_bug.cgi?id=110884  or
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101778  ?


Thanks for catching that. Yes, it should be 110884. I installed the 
attached to Gnulib.From dcf286c586069684fe4d5bb2bd770394cd7cdad6 Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Sun, 6 Aug 2023 12:43:05 -0700
Subject: [PATCH] readutmp: fix comment bug ID

* lib/readutmp.c: Fix comment (thanks to Bruno Haible).
---
 lib/readutmp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/readutmp.c b/lib/readutmp.c
index b8eba076fa..4e1d7ec26b 100644
--- a/lib/readutmp.c
+++ b/lib/readutmp.c
@@ -47,7 +47,7 @@
 # pragma GCC diagnostic ignored "-Wsizeof-pointer-memaccess"
 #endif
 
-/* Work around .  */
+/* Work around .  */
 #if 11 <= __GNUC__
 # pragma GCC diagnostic ignored "-Wstringop-overread"
 #endif
-- 
2.39.2



bug#64937: "who" reports funny dates

2023-08-04 Thread Bruno Haible
Paul Eggert wrote:
> Thanks for doing all that work. I looked into it, and found a problem: a 
> command like "who /var/log/wtmp" stops working because the systemd 
> emulation of read_utmp only supports plain "who" (roughly equivalent to 
> "who /var/run/utmp" on Fedora).

Probably the FILE argument to 'who' and to 'users' should be deprecated?
Since in systemd mode, the only supported value for FILE is /var/run/utmp.

> Although I toyed with the idea of simplifying readutmp.h 
> further, by moving most of it into readutmp.c and having just struct 
> gl_utmp public (this would simplify coreutils quite a bit), I ran out of 
> time and patience and decided to ship what I had.

Yes, I see how much contortions (strncpy etc.) these not-NUL-terminated
strings cause. And two separate code paths, one for the systemd mode and
one for all other platforms, is not ideal from the code coverage/testing/QA
perspective either.

I didn't tackle this, because before the add_utmp function existed, it
would have caused many extra malloc() calls on all platforms.

Bruno








bug#64937: "who" reports funny dates

2023-08-04 Thread Bruno Haible
Paul Eggert wrote:
> 0001-maint-Update-after-gnulib-module-readutmp-changed.patch

> +/* Work around ,
> +   triggered by STREQ_LEN with a negative length.  */
> +#if 11 <= __GNUC__
> +# pragma GCC diagnostic ignored "-Wstringop-overread"
> +#endif

The mentioned GCC bug is about a -Wanalyzer-use-after-free false positive.
I guess you meant https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110884 or
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101778 ?

Bruno








bug#64937: "who" reports funny dates

2023-08-04 Thread Thorsten Kukuk via GNU coreutils Bug Reports


Hi,

On Fri, Aug 04, Paul Eggert wrote:

> Thanks for doing all that work. I looked into it, and found a problem: a 
> command like "who /var/log/wtmp" stops working because the systemd 
> emulation of read_utmp only supports plain "who" (rougnly equivalent to 
> "who /var/run/utmp" on Fedora). So I installed it into coreutils, but 
> the default is systemd is disabled. This should give people time to 
> experiment with it.
> 
> Thorsten, is there some way to get the equivalent of /var/log/wtmp with 
> systemd?

systemd does not collect wtmp data, because the applications don't 
report this data to systemd. And I don't think it makes sense to 
implement that or that such patches would be accepted by systemd
developers.

wtmp uses the same struct as utmp and thus faces the same problems,
including the Y2038 issue.
For this reason we (openSUSE/SUSE) switched to wtmpdb:
https://github.com/thkukuk/wtmpdb and don't support /var/log/wtmp
anymore.

And yes, "who /var/log/wtmp" will not work with this, too. But is this
really a required or usefull use case?
/usr/bin/last can give you the same output.

  Thorsten

-- 
Thorsten Kukuk, Distinguished Engineer, Senior Architect, Future Technologies
SUSE Software Solutions Germany GmbH, Frankenstraße 146, 90461 Nuernberg, 
Germany
Managing Director: Ivo Totev, Andrew McDonald, Werner Knoblich
(HRB 36809, AG Nürnberg)





bug#64937: "who" reports funny dates

2023-08-04 Thread Paul Eggert
Thanks for doing all that work. I looked into it, and found a problem: a 
command like "who /var/log/wtmp" stops working because the systemd 
emulation of read_utmp only supports plain "who" (rougnly equivalent to 
"who /var/run/utmp" on Fedora). So I installed it into coreutils, but 
the default is systemd is disabled. This should give people time to 
experiment with it.


Thorsten, is there some way to get the equivalent of /var/log/wtmp with 
systemd?


Also, I simplified the use of the new readutmp interface a bit, by going 
back to the old way where you simply call 'free' once to free the 
storage. Although I toyed with the idea of simplifying readutmp.h 
further, by moving most of it into readutmp.c and having just struct 
gl_utmp public (this would simplify coreutils quite a bit), I ran out of 
time and patience and decided to ship what I had. So I nstalled the 
first ten attached patches into Gnulib, and the last patch into coreutils.


I haven't tested this with the latest systemd so there could well be 
typos in that part of the code.From 39a4cb0afdf4f2a1e6c2f3176b84e5b4cfe8996d Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Thu, 3 Aug 2023 15:31:48 -0700
Subject: [PATCH 1/9] readutmp: simplify extract_trimmed_name via ximemdup0

* lib/readutmp.c (extract_trimmed_name): Simplify.
* modules/readutmp (Depends-on):
Add strnlen, which was a missing dependency.

* lib/readutmp.c: Include xmemdup0.
(extract_trimmed_name): Simplify.
* modules/readutmp (Depends-on): Add xmemdup0.
Add strnlen, which was a missing dependency already.
---
 ChangeLog|  7 +++
 lib/readutmp.c   | 28 +++-
 modules/readutmp |  1 +
 3 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index b84cece6ff..7fa4e7b64a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2023-08-03  Paul Eggert  
+
+	readutmp: simplify extract_trimmed_name via ximemdup0
+	* lib/readutmp.c (extract_trimmed_name): Simplify.
+	* modules/readutmp (Depends-on):
+	Add strnlen, which was a missing dependency.
+
 2023-08-03  Bruno Haible  
 
 	alignasof, stdalign: Avoid some -Wundef warnings from config.h.
diff --git a/lib/readutmp.c b/lib/readutmp.c
index 11dd1655c5..9057a36494 100644
--- a/lib/readutmp.c
+++ b/lib/readutmp.c
@@ -47,29 +47,23 @@
 # pragma GCC diagnostic ignored "-Wsizeof-pointer-memaccess"
 #endif
 
+/* Work around .  */
+#if 11 <= __GNUC__
+# pragma GCC diagnostic ignored "-Wstringop-overread"
+#endif
+
 /* Copy UT_USER (UT) into storage obtained from malloc.  Then remove any
trailing spaces from the copy, NUL terminate it, and return the copy.  */
 
 char *
 extract_trimmed_name (const STRUCT_UTMP *ut)
 {
-  char *p, *trimmed_name;
-
-#if READUTMP_USE_SYSTEMD
-  trimmed_name = xstrdup (UT_USER (ut));
-#else
-  trimmed_name = xmalloc (UT_USER_SIZE + 1);
-  strncpy (trimmed_name, UT_USER (ut), UT_USER_SIZE);
-  /* Append a trailing NUL.  Some systems pad names shorter than the
- maximum with spaces, others pad with NULs.  */
-  trimmed_name[UT_USER_SIZE] = '\0';
-#endif
-  /* Remove any trailing spaces.  */
-  for (p = trimmed_name + strlen (trimmed_name);
-   trimmed_name < p && p[-1] == ' ';
-   *--p = '\0')
-;
-  return trimmed_name;
+  char const *name = UT_USER (ut);
+  idx_t len = strnlen (name, UT_USER_SIZE);
+  char const *p;
+  for (p = name + len; name < p && p[-1] == ' '; p--)
+continue;
+  return ximemdup0 (name, p - name);
 }
 
 #if READ_UTMP_SUPPORTED
diff --git a/modules/readutmp b/modules/readutmp
index 04893a4487..484edd1842 100644
--- a/modules/readutmp
+++ b/modules/readutmp
@@ -12,6 +12,7 @@ extensions
 xalloc
 stdbool
 stdint
+strnlen
 sys_time
 fopen-gnu
 unlocked-io-internal
-- 
2.39.2

From 1ccde926759e8638d4b86de3dabbd948ad921edc Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Thu, 3 Aug 2023 15:53:27 -0700
Subject: [PATCH 2/9] =?UTF-8?q?readutmp:=20go=20back=20to=20simple=20?=
 =?UTF-8?q?=E2=80=98free=E2=80=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Omit the new free_utmp function.  Instead, allocate storage
in one block, so that using code can still just call ‘free’.
* lib/readutmp.c (struct utmp_alloc) [READUTMP_USE_SYSTEMD]: New type.
(add_utmp) [READUTMP_USE_SYSTEMD]: New function.
(read_utmp) [READUTMP_USE_SYSTEMD]: Use it.
Also, use malloc a bit less heavily.
(free_utmp): Remove.
* tests/test-readutmp.c (main): Call free, not free_utmp.
---
 ChangeLog |  10 ++
 NEWS  |   4 +-
 lib/readutmp.c| 285 +++---
 lib/readutmp.h|   4 -
 tests/test-readutmp.c |   4 +-
 5 files changed, 167 insertions(+), 140 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7fa4e7b64a..56b27d129f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2023-08-03  Paul Eggert  
 
+	readutmp: go back to simple ‘free’
+	Omit the new free_utmp 

bug#64937: "who" reports funny dates

2023-08-02 Thread Bruno Haible
I wrote:
> The proposed patch is attached.

Oops, I missed a sizeof of the ut_id field. A corrected patch is attached.

>From 97be578b107e7b87e32e0c3c2d49dc550489415b Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Wed, 2 Aug 2023 01:32:55 +0200
Subject: [PATCH] maint: Update after gnulib module 'readutmp' changed

For year-2038 safety on Linux/{x86,arm}, use systemd APIs.

* configure.ac: Don't test whether 'struct utmp' and 'struct utmpx' have
the ut_host field; this is now done in gnulib's readutmp module.
* src/system.h (STREQ_LEN): Allow passing a third argument with value
-1.
* src/pinky.c: Test HAVE_STRUCT_XTMP_UT_HOST instead of HAVE_UT_HOST.
(print_entry): Support the situation where ut_line is a 'char *' rather
than a 'char[]' of fixed size. Likewise for ut_user and ut_host.
* src/who.c: Test HAVE_STRUCT_XTMP_UT_HOST instead of HAVE_UT_HOST.
(print_user): Support the situation where ut_line is a 'char *' rather
than a 'char[]' of fixed size. Likewise for ut_user and ut_host.
(print_deadprocs, print_login, print_initspawn, scan_entries): Likewise.
(make_id_equals_comment): Likewise for ut_id.
(who): Free resources before returning.
* src/users.c (users): Free resources before returning.
* src/local.mk: Link the programs 'pinky', 'uptime', 'users', 'who' with
$(READUTMP_LIB).
---
 configure.ac | 30 --
 src/local.mk |  6 ++
 src/pinky.c  | 41 ++--
 src/system.h |  6 +-
 src/users.c  |  1 +
 src/who.c| 59 
 6 files changed, 83 insertions(+), 60 deletions(-)

diff --git a/configure.ac b/configure.ac
index 33441a82f..afc1098f7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -406,36 +406,6 @@ AC_DEFUN([coreutils_DUMMY_1],
 ])
 coreutils_DUMMY_1
 
-AC_MSG_CHECKING([ut_host in struct utmp])
-AC_CACHE_VAL([su_cv_func_ut_host_in_utmp],
-[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include 
-   #include 
-   struct utmp ut;
-   int s = sizeof ut.ut_host;]])],
-  [su_cv_func_ut_host_in_utmp=yes],
-  [su_cv_func_ut_host_in_utmp=no])])
-AC_MSG_RESULT([$su_cv_func_ut_host_in_utmp])
-if test $su_cv_func_ut_host_in_utmp = yes; then
-  have_ut_host=1
-  AC_DEFINE([HAVE_UT_HOST], [1], [FIXME])
-fi
-
-if test -z "$have_ut_host"; then
-  AC_MSG_CHECKING([ut_host in struct utmpx])
-  AC_CACHE_VAL([su_cv_func_ut_host_in_utmpx],
-  [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include 
- #include 
- struct utmpx ut;
- int s = sizeof ut.ut_host;]])],
-[su_cv_func_ut_host_in_utmpx=yes],
-[su_cv_func_ut_host_in_utmpx=no])])
-  AC_MSG_RESULT([$su_cv_func_ut_host_in_utmpx])
-  if test $su_cv_func_ut_host_in_utmpx = yes; then
-AC_DEFINE([HAVE_UTMPX_H], [1], [FIXME])
-AC_DEFINE([HAVE_UT_HOST], [1], [FIXME])
-  fi
-fi
-
 GNULIB_BOOT_TIME([gl_ADD_PROG([optional_bin_progs], [uptime])])
 
 AC_SYS_POSIX_TERMIOS()
diff --git a/src/local.mk b/src/local.mk
index cb9b39274..4d7df2789 100644
--- a/src/local.mk
+++ b/src/local.mk
@@ -317,6 +317,12 @@ src_who_LDADD += $(GETADDRINFO_LIB)
 src_hostname_LDADD += $(GETHOSTNAME_LIB)
 src_uname_LDADD += $(GETHOSTNAME_LIB)
 
+# for read_utmp
+src_pinky_LDADD += $(READUTMP_LIB)
+src_uptime_LDADD += $(READUTMP_LIB)
+src_users_LDADD += $(READUTMP_LIB)
+src_who_LDADD += $(READUTMP_LIB)
+
 # for strsignal
 src_kill_LDADD += $(LIBTHREAD)
 
diff --git a/src/pinky.c b/src/pinky.c
index 381e753b6..47abd7758 100644
--- a/src/pinky.c
+++ b/src/pinky.c
@@ -62,7 +62,7 @@ static bool include_home_and_shell = true;
 static bool do_short_format = true;
 
 /* if true, display the ut_host field. */
-#ifdef HAVE_UT_HOST
+#if HAVE_STRUCT_XTMP_UT_HOST
 static bool include_where = true;
 #endif
 
@@ -206,7 +206,8 @@ print_entry (const STRUCT_UTMP *utmp_ent)
 #define DEV_DIR_WITH_TRAILING_SLASH "/dev/"
 #define DEV_DIR_LEN (sizeof (DEV_DIR_WITH_TRAILING_SLASH) - 1)
 
-  char line[sizeof (utmp_ent->ut_line) + DEV_DIR_LEN + 1];
+#ifdef UT_LINE_SIZE
+  char line[DEV_DIR_LEN + UT_LINE_SIZE + 1];
   char *p = line;
 
   /* Copy ut_line into LINE, prepending '/dev/' if ut_line is not
@@ -214,7 +215,18 @@ print_entry (const STRUCT_UTMP *utmp_ent)
  absolute file name in ut_line.  */
   if ( ! IS_ABSOLUTE_FILE_NAME (utmp_ent->ut_line))
 p = stpcpy (p, DEV_DIR_WITH_TRAILING_SLASH);
-  stzncpy (p, utmp_ent->ut_line, sizeof (utmp_ent->ut_line));
+  stzncpy (p, utmp_ent->ut_line, UT_LINE_SIZE);
+#else
+  /* If ut_line contains a space, the device name starts after the space,
+ else at the beginning.  */
+  char *line = xmalloc (DEV_DIR_LEN + strlen (utmp_ent->ut_line) + 1);
+  char *space = strchr (utmp_ent->ut_line, ' ');
+  char *device = (space != NULL ? space + 1 : utmp_ent->ut_line);
+  if ( ! IS_ABSOLUTE_FILE_NAME (device))
+stpcpy (stpcpy (line, DEV_DIR_WITH_TRAILING_SLASH), device);
+  

bug#64937: "who" reports funny dates

2023-08-02 Thread Thorsten Kukuk via GNU coreutils Bug Reports


Hi,

On Tue, Aug 01, Bruno Haible wrote:

> Thorsten Kukuk wrote:
> > If you haven't seen yet, I made some time ago a mapping
> > between utmp struct entries and libsystemd functions: 
> > https://github.com/thkukuk/utmpx/blob/main/utmp-to-logind.md
> 
> Thanks. This is helpful.
> 
> The only problem with this mapping is for the ut_line row, which
> used to contain, for inbound ssh, the pty device name. It is not easy
> to find the pty name in this situation; at least, none of the systemd
> APIs and /run/systemd/** files that I looked at helped.

You mean you don't see a TTY on ssh sessions?

openssh is really special: it does not need a TTY for all kind of ssh
sessions, and thus only opens a TTY if needed after creating the
logind session. Thus the logind session does not contain the TTY 
informations.
systemd-logind v254 provides now an interface for this case, which
allows to set the TTY later. For openssh you need this patch:

https://github.com/thkukuk/utmpx/blob/main/patches/openssh/logind-set-tty.patch

> The major changes are:
> * Entries without BOOT_TIME or USER_PROCESS flag are gone. This includes
>   - runlevel and possibly "old time" / "new time" entries, which I don't know
> how to get from systemd,

systemd has no "runlevel", this entries don't exists.
I haven't found an application which creates "old time" / "new time"
entries, thus I think they can be ignored.

>   - entries for pseudo-terminals (xterm etc.) that are not login shells;
> I don't know how to get them from systemd either, and (IMO) they were
> uninteresting anyway,

Yes, this is a problem or not, because on the other side,  it solves a
problem. E.g.
* xterm creates entries for pseudo-terminals
* gnome-terminal does not create entries for pseudo-terminals

That was confusing in the past and is now consistent.

> * The pids now refer to the session leader, which is a parent (or ancestor)
>   of the process which has allocated the pty.

Depends on your application. For the majority of applications, which we
evaluated, the PIDs reported by logind were identical to the PID from utmp.

> * In the ut_line field ("Device" column) I added extra info about the
>   service name, in this case "sshd". I imagine that is at least as useful as
>   knowing the pty name ("pts/4").

See above, this is a special openssh problem, we need to teach openssh
to report the TTY to logind, too.

  Thorsten

-- 
Thorsten Kukuk, Distinguished Engineer, Senior Architect, Future Technologies
SUSE Software Solutions Germany GmbH, Frankenstraße 146, 90461 Nuernberg, 
Germany
Managing Director: Ivo Totev, Andrew McDonald, Werner Knoblich
(HRB 36809, AG Nürnberg)





bug#64937: "who" reports funny dates

2023-08-01 Thread Bruno Haible
> Here are the changes I committed in gnulib.

And here are the proposed changes for coreutils. Tested on a Fedora Rawhide
system, prepared from
https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Workstation/x86_64/iso/Fedora-Workstation-Live-x86_64-Rawhide-20230729.n.0.iso

The user-visible changes introduced by this change (when linking with
libsystemd) are, as far as I can see:

* "uptime", "users", "who -q" reports fewer users (because ptys without login
  are not counted).
* "who -d" does not report anything any more.
* "who -r" does not report anything any more.
* "who -t" does not report anything any more.
* "who -u" does not report ptys without login any more. The order is arbitrary. 
Example:
Without systemd:

brunoseat02023-07-30 11:25   ?  1663 (login screen)
brunotty2 2023-07-30 11:25  old 1663 (tty2)
brunopts/32023-08-01 01:36 22:33   30619 (:0)
otherpts/42023-08-01 17:19 06:50   40513 (::1)

With systemd:

othersshd pts/4   2023-08-01 17:19 06:50   40513 (::1)
brunoseat02023-07-30 11:25   ?  1593
brunotty2 2023-07-30 11:25  old 1593

* pinky $USER
does not report a host any more (and thus does not spend time trying
to do a DNS lookup of "login screen" and "tty2"). Example:
Without systemd:

LoginName TTY  Idle   When Where
brunoBruno Haible?seat0?  2023-07-30 11:25 login screen
brunoBruno Haible tty2 2d 2023-07-30 11:25 tty2
brunoBruno Haible pts/322:39  2023-08-01 01:36 :0

With systemd:

LoginName TTY  Idle   When Where
brunoBruno Haible?seat0?  2023-07-30 11:25
brunoBruno Haible tty2 2d 2023-07-30 11:25


The proposed patch is attached.

Note: Instead of the idiom

   #ifdef UT_HOST_SIZE
 (code for bounded ut_host)
   #else
 (code for unbounded ut_host)
   #endif

one could also write

   if (UT_HOST_SIZE >= 0)
 {
   (code for bounded ut_host)
 }
   else
 {
   (code for unbounded ut_host)
 }

It's just a matter of style whether one prefers #ifs or implicit dead code.

>From d80eea8fb087e9504a6dad27e1a880227f67915a Mon Sep 17 00:00:00 2001
From: Bruno Haible 
Date: Wed, 2 Aug 2023 01:32:55 +0200
Subject: [PATCH] maint: Update after gnulib module 'readutmp' changed

For year-2038 safety on Linux/{x86,arm}, use systemd APIs.

* configure.ac: Don't test whether 'struct utmp' and 'struct utmpx' have
the ut_host field; this is now done in gnulib's readutmp module.
* src/system.h (STREQ_LEN): Allow passing a third argument with value
-1.
* src/pinky.c: Test HAVE_STRUCT_XTMP_UT_HOST instead of HAVE_UT_HOST.
(print_entry): Support the situation where ut_line is a 'char *' rather
than a 'char[]' of fixed size. Likewise for ut_user and ut_host.
* src/who.c: Test HAVE_STRUCT_XTMP_UT_HOST instead of HAVE_UT_HOST.
(print_user): Support the situation where ut_line is a 'char *' rather
than a 'char[]' of fixed size. Likewise for ut_user and ut_host.
(print_deadprocs, print_login, print_initspawn, scan_entries): Likewise.
(who): Free resources before returning.
* src/users.c (users): Free resources before returning.
* src/local.mk: Link the programs 'pinky', 'uptime', 'users', 'who' with
$(READUTMP_LIB).
---
 configure.ac | 30 --
 src/local.mk |  6 ++
 src/pinky.c  | 41 ++---
 src/system.h |  6 +-
 src/users.c  |  1 +
 src/who.c| 44 ++--
 6 files changed, 72 insertions(+), 56 deletions(-)

diff --git a/configure.ac b/configure.ac
index 33441a82f..afc1098f7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -406,36 +406,6 @@ AC_DEFUN([coreutils_DUMMY_1],
 ])
 coreutils_DUMMY_1
 
-AC_MSG_CHECKING([ut_host in struct utmp])
-AC_CACHE_VAL([su_cv_func_ut_host_in_utmp],
-[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include 
-   #include 
-   struct utmp ut;
-   int s = sizeof ut.ut_host;]])],
-  [su_cv_func_ut_host_in_utmp=yes],
-  [su_cv_func_ut_host_in_utmp=no])])
-AC_MSG_RESULT([$su_cv_func_ut_host_in_utmp])
-if test $su_cv_func_ut_host_in_utmp = yes; then
-  have_ut_host=1
-  AC_DEFINE([HAVE_UT_HOST], [1], [FIXME])
-fi
-
-if test -z "$have_ut_host"; then
-  AC_MSG_CHECKING([ut_host in struct utmpx])
-  AC_CACHE_VAL([su_cv_func_ut_host_in_utmpx],
-  [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include 
- #include 
- struct utmpx ut;
- int s = sizeof ut.ut_host;]])],
-[su_cv_func_ut_host_in_utmpx=yes],
-[su_cv_func_ut_host_in_utmpx=no])])
-  AC_MSG_RESULT([$su_cv_func_ut_host_in_utmpx])
-  if test $su_cv_func_ut_host_in_utmpx = yes; then
-AC_DEFINE([HAVE_UTMPX_H], [1], 

bug#64937: "who" reports funny dates

2023-08-01 Thread Bruno Haible
Thorsten Kukuk wrote:
> If you haven't seen yet, I made some time ago a mapping
> between utmp struct entries and libsystemd functions: 
> https://github.com/thkukuk/utmpx/blob/main/utmp-to-logind.md

Thanks. This is helpful.

The only problem with this mapping is for the ut_line row, which
used to contain, for inbound ssh, the pty device name. It is not easy
to find the pty name in this situation; at least, none of the systemd
APIs and /run/systemd/** files that I looked at helped.

> But be aware:
> 1. you need to extend ut_tv from 32bit time_t to 64bit time_t, or your
> patch will not survive 2038.

This is already done by the 'year2038' module of Gnulib, which
coreutils and many other packages use.

> 2. the string entries are size limited in struct utmp, but are not with
> libsystemd. So could be that you need to truncate device names, user
> names and host names.

Thanks for the hint. Truncating would mean to introduce arbitrary limits,
which is against the GNU Coding Standards
. Hence
we'll happily use arbitrary-length strings in our code.

Paul Eggert wrote:
> This suggests that Gnulib needs to redo the readutmp API so that it's 
> not tied to struct utmpx's fixed string lengths. That's a bit of a 
> hassle but should be doable (change char array to char *). An advantage 
> is that Gnulib is a source-code library and so we can make binary- (and 
> even source-) incompatible changes to the API without too much trouble.

For the moment, I've extended the 'readutmp' module to use arbitrary-
length strings only when compiling with libsystemd.

Here are the changes I committed in gnulib.


2023-08-01  Bruno Haible  

readutmp: Small changes to reduce the code size on the coreutils side.
* m4/readutmp.m4 (gl_READUTMP): Test also for the ut_host field in
'struct utmpx' and 'struct utmp'.
* lib/readutmp.h (HAVE_STRUCT_XTMP_UT_HOST): New macro.
(UT_USER_SIZE): Define also as a macro. Set to -1 if
READUTMP_USE_SYSTEMD.
(UT_LINE_SIZE, UT_HOST_SIZE): New constants and macros.

2023-08-01  Bruno Haible  

readutmp: For year-2038 safety on Linux/{x86,arm}, use systemd APIs.
Suggested by Thorsten Kukuk  in
 and
.
* m4/systemd.m4: New file.
* m4/readutmp.m4 (gl_READUTMP): Require gl_SYSTEMD_CHOICE. Set
READUTMP_LIB. Conditionally define READUTMP_USE_SYSTEMD.
* lib/readutmp.h: For READUTMP_USE_SYSTEMD, include  and
.
(struct gl_utmp): New type.
(UTMP_STRUCT_NAME, UT_TIME_MEMBER, UT_EXIT_E_TERMINATION,
UT_EXIT_E_EXIT, UT_USER, HAVE_STRUCT_XTMP_UT_EXIT,
HAVE_STRUCT_XTMP_UT_ID, HAVE_STRUCT_XTMP_UT_PID): Define differently for
READUTMP_USE_SYSTEMD.
(UT_USER_SIZE): Don't define for READUTMP_USE_SYSTEMD.
(UT_TYPE_EQ, UT_TYPE_NOT_DEFINED, READ_UTMP_SUPPORTED): Define also for
READUTMP_USE_SYSTEMD.
(free_utmp): New declaration.
* lib/readutmp.c: Add new includes for READUTMP_USE_SYSTEMD.
(extract_trimmed_name): Adapt to READUTMP_USE_SYSTEMD.
(get_boot_time_uncached, get_boot_time, guess_pty_name): New functions.
(read_utmp): New implementation for READUTMP_USE_SYSTEMD.
(free_utmp): New function.
* tests/test-readutmp.c (main): At the end, invoke free_utmp.
* modules/readutmp (Files): Add m4/systemd.m4.
(Link): New section.
* modules/readutmp-tests (Makefile.am): Link test-readutmp with
READUTMP_LIB.
* NEWS: Mention the free_utmp function and the READUTMP_LIB link
requirement.


When the output of the 'test-readutmp' program without libsystemd is
 ==
Here are the read_utmp results.
Flags: B = Boot, U = User Process

  Termi‐  Flags
Time (GMT) User  DevicePIDnation Exit  B U
--- -- --- -- --   - -
2023-07-30 09:25:15 reboot ~00 0   X  
2023-07-30 09:25:31 runlevel   ~   530 0  
2023-07-30 09:25:48 bruno  seat0 16630 0 X
2023-07-30 09:25:48 bruno  tty2  16630 0 X
2023-07-30 09:31:17pts/1 32100 0  
2023-07-31 23:36:52 bruno  pts/3306190 0 X
2023-08-01 15:19:26 other  pts/4405130 0 X
2023-08-01 19:02:20pts/5433760 1  
 ==

with libsystemd it is:

 

bug#64937: "who" reports funny dates

2023-07-31 Thread Thorsten Kukuk via GNU coreutils Bug Reports


Hi,

On Sun, Jul 30, Paul Eggert wrote:

> Thorsten's draft coreutils patches 
>  are a bit 
> long, and I'm hoping we can simplify this by packaging the fix inside 
> Gnulib (much as we already packaged the fix for  not working on 
> 32-bit GNU/Linux x86 and ARM when _TIME_BITS is 64[1]), so that we 
> needn't patch Coreutils other than to upgrade Gnulib version.

If you haven't seen yet, I made some time ago a mapping
between utmp struct entries and libsystemd functions: 
https://github.com/thkukuk/utmpx/blob/main/utmp-to-logind.md

But be aware:
1. you need to extend ut_tv from 32bit time_t to 64bit time_t, or your
patch will not survive 2038.
2. the string entries are size limited in struct utmp, but are not with
libsystemd. So could be that you need to truncate device names, user
names and host names.

  Thorsten

-- 
Thorsten Kukuk, Distinguished Engineer, Senior Architect, Future Technologies
SUSE Software Solutions Germany GmbH, Frankenstraße 146, 90461 Nuernberg, 
Germany
Managing Director: Ivo Totev, Andrew McDonald, Werner Knoblich
(HRB 36809, AG Nürnberg)





bug#64937: "who" reports funny dates

2023-07-31 Thread Paul Eggert

On 2023-07-31 00:08, Thorsten Kukuk wrote:

1. you need to extend ut_tv from 32bit time_t to 64bit time_t, or your
patch will not survive 2038.


Yes, that's the plan. Gnulib's readutmp module already does this, in 
apps that also use the year2038 or year2038-recommended modules (which 
most do).



2. the string entries are size limited in struct utmp, but are not with
libsystemd. So could be that you need to truncate device names, user
names and host names.


This suggests that Gnulib needs to redo the readutmp API so that it's 
not tied to struct utmpx's fixed string lengths. That's a bit of a 
hassle but should be doable (change char array to char *). An advantage 
is that Gnulib is a source-code library and so we can make binary- (and 
even source-) incompatible changes to the API without too much trouble.


Thanks for the advice.





bug#64937: "who" reports funny dates

2023-07-30 Thread Bruno Haible
Paul Eggert wrote:
> If I understand that discussion correctly, the idea is to switch from 
> utmp/utmpx to the systemd interface once systemd 254 comes out.
> 
> As it happens, systemd 254 was published Friday.

It's already contained in Fedora Rawhide.

> It'd be good to get it working with coreutils.

I've installed that Fedora Rawhide from yesterday and am working on a
prototype...

> I'm hoping we can simplify this by packaging the fix inside 
> Gnulib

Yes. Since not only coreutils, but also inetutils, uses the gnulib
module 'readutmp', it makes sense to put the fix into this gnulib
module.

Specific users, like 'uptime' in coreutils, can optimize things
afterwards when they need only a small subset, rather than all, of
the data returned by read_utmp().

Bruno








bug#64937: "who" reports funny dates

2023-07-30 Thread Paul Eggert

On 2023-07-30 04:02, Pádraig Brady wrote:

Yes I think the consensus is to switch away from the utmp API,
which was recently discussed at:
https://lists.gnu.org/archive/html/coreutils/2023-06/msg00024.html


If I understand that discussion correctly, the idea is to switch from 
utmp/utmpx to the systemd interface once systemd 254 comes out.


As it happens, systemd 254 was published Friday. It'd be good to get it 
working with coreutils.


Thorsten's draft coreutils patches 
 are a bit 
long, and I'm hoping we can simplify this by packaging the fix inside 
Gnulib (much as we already packaged the fix for  not working on 
32-bit GNU/Linux x86 and ARM when _TIME_BITS is 64[1]), so that we 
needn't patch Coreutils other than to upgrade Gnulib version.


Is there any way to test this stuff easily on a platform like Fedora 38 
that is running systemd 253? That is, can I merely build the systemd 
libraries and link to them (how?), or would I have to replace the entire 
systemd ecosystem?


[1]: https://lists.gnu.org/r/bug-gnulib/2023-07/msg00159.html





bug#64937: "who" reports funny dates

2023-07-30 Thread Sven Joachim
On 2023-07-29 17:30 -0700, Paul Eggert wrote:

> On 2023-07-29 12:44, Pádraig Brady wrote:
>> I tried a quick build with -D__WORDSIZE_TIME64_COMPAT32=1
>> which is what glibc uses to force the smaller time types.
>> However that didn't fix the issue, so I'll need to look a bit more,
>> and how to get only utmp access restricted to 32 bit types.

I guess -D__WORDSIZE_TIME64_COMPAT32=1 does not cut it because
bits/wordsize.h #defines __WORDSIZE_TIME64_COMPAT32 as 0, overriding the
commandline definition.

> What's Debian's and/or Fedora's plan for fixing /'s
> Y2038 bugs? (Or is the idea to remove the  API
> before 2038? :-)

I don't really know.  In the near future Debian plans to enable
-D_TIME_BITS=64 by default on most 32-bit architectures[1] though, and
then the utmp interface is going to break.  I have notified the Debian
glibc maintainers[2], but the problem needs to be addressed by glibc
upstream.

> See:
>
> https://lwn.net/Articles/925068/
>
> https://sourceware.org/glibc/wiki/Y2038ProofnessDesign#utmp_types_and_APIs

Thanks for the links.  And for fixing the bug. :-)

Cheers,
   Sven


1. https://lists.debian.org/debian-devel/2023/05/msg00168.html
2. https://bugs.debian.org/1042562





bug#64937: "who" reports funny dates

2023-07-30 Thread Pádraig Brady

On 30/07/2023 01:30, Paul Eggert wrote:

On 2023-07-29 12:44, Pádraig Brady wrote:

I tried a quick build with -D__WORDSIZE_TIME64_COMPAT32=1
which is what glibc uses to force the smaller time types.
However that didn't fix the issue, so I'll need to look a bit more,
and how to get only utmp access restricted to 32 bit types.


I looked into that, and installed the attached patches into Gnulib and
Coreutils respectively; these should work around the problem so I'll
boldly close the bug report.

These patches are quite a hack, though, and (obviously) stop working
after the year 2038.

What's Debian's and/or Fedora's plan for fixing /'s
Y2038 bugs? (Or is the idea to remove the  API before
2038? :-)

See:

https://lwn.net/Articles/925068/

https://sourceware.org/glibc/wiki/Y2038ProofnessDesign#utmp_types_and_APIs


Thanks Paul.

Yes I think the consensus is to switch away from the utmp API,
which was recently discussed at:
https://lists.gnu.org/archive/html/coreutils/2023-06/msg00024.html

cheers,
Pádraig





bug#64937: "who" reports funny dates

2023-07-29 Thread Paul Eggert

On 2023-07-29 12:44, Pádraig Brady wrote:

I tried a quick build with -D__WORDSIZE_TIME64_COMPAT32=1
which is what glibc uses to force the smaller time types.
However that didn't fix the issue, so I'll need to look a bit more,
and how to get only utmp access restricted to 32 bit types.


I looked into that, and installed the attached patches into Gnulib and 
Coreutils respectively; these should work around the problem so I'll 
boldly close the bug report.


These patches are quite a hack, though, and (obviously) stop working 
after the year 2038.


What's Debian's and/or Fedora's plan for fixing /'s 
Y2038 bugs? (Or is the idea to remove the  API before 
2038? :-)


See:

https://lwn.net/Articles/925068/

https://sourceware.org/glibc/wiki/Y2038ProofnessDesign#utmp_types_and_APIsFrom c408d9a53dbdaf48b555f216e250a2b3b8e48113 Mon Sep 17 00:00:00 2001
From: Paul Eggert 
Date: Sat, 29 Jul 2023 17:06:42 -0700
Subject: [PATCH] readutmp: work around glibc utmpx bug

When compiled with _TIME_BITS=64, glibc  does not work,
because the files use 32-bit time_t and the code passes this to
the user unmodified, but  defines a struct with 64-bit
time_t.  Work around this compatibility bug.  Problem reported
by Jakub Wilk via Sven Joachim .
* lib/readutmp.c (copy_utmp_entry): New function.
(read_utmp): Use it.
---
 ChangeLog | 10 +++
 doc/glibc-functions/getutmp.texi  | 13 +
 doc/glibc-functions/getutmpx.texi | 13 +
 doc/glibc-headers/utmp.texi   | 13 +
 doc/posix-headers/utmpx.texi  | 13 +
 doc/year2038.texi |  8 ++
 lib/readutmp.c| 47 ++-
 7 files changed, 116 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 53e22f3c98..aad4e95ef8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2023-07-29  Paul Eggert  
+
+	readutmp: work around glibc utmpx bug
+	When compiled with _TIME_BITS=64, glibc  does not work,
+	because the files use 32-bit time_t and the code passes this to
+	the user unmodified, but  defines a struct with 64-bit
+	time_t.  Work around this compatibility bug.
+	* lib/readutmp.c (copy_utmp_entry): New function.
+	(read_utmp): Use it.
+
 2023-07-29  Bruno Haible  
 
 	wcsrtombs tests: Renumber tests.
diff --git a/doc/glibc-functions/getutmp.texi b/doc/glibc-functions/getutmp.texi
index 2628441e13..b53369a597 100644
--- a/doc/glibc-functions/getutmp.texi
+++ b/doc/glibc-functions/getutmp.texi
@@ -26,4 +26,17 @@ Portability problems not fixed by Gnulib:
 @item
 This function is missing on some platforms:
 FreeBSD 13.0, OpenBSD 6.7, Minix 3.1.8, AIX 5.1, HP-UX 11, Cygwin 2.9, mingw, MSVC 14, Android 9.0.
+@item
+On some platforms, this function does not support timestamps past the
+year 2038:
+glibc 2.38 on 32-bit platforms like x86 and ARM where @code{time_t}
+was historically 32 bits.
+@item
+On some platforms, this function misbehaves if the @code{year2038} or
+@code{year2038-recommended} modules are used and the program is
+configured without the @option{--disable-year2038} option.
+The @code{readutmp} module works around this problem:
+glibc 2.38 on 32-bit platforms like x86 and ARM where @code{time_t}
+was historically 32 bits.
+@xref{Avoiding the year 2038 problem}.
 @end itemize
diff --git a/doc/glibc-functions/getutmpx.texi b/doc/glibc-functions/getutmpx.texi
index 0ebc01978b..bee96fc239 100644
--- a/doc/glibc-functions/getutmpx.texi
+++ b/doc/glibc-functions/getutmpx.texi
@@ -26,4 +26,17 @@ Portability problems not fixed by Gnulib:
 @item
 This function is missing on some platforms:
 FreeBSD 13.0, OpenBSD 6.7, Minix 3.1.8, AIX 5.1, HP-UX 11, Cygwin 2.9, mingw, MSVC 14, Android 9.0.
+@item
+On some platforms, this function does not support timestamps past the
+year 2038:
+glibc 2.38 on 32-bit platforms like x86 and ARM where @code{time_t}
+was historically 32 bits.
+@item
+On some platforms, this function misbehaves if the @code{year2038} or
+@code{year2038-recommended} modules are used and the program is
+configured without the @option{--disable-year2038} option.
+The @code{readutmp} module works around this problem:
+glibc 2.38 on 32-bit platforms like x86 and ARM where @code{time_t}
+was historically 32 bits.
+@xref{Avoiding the year 2038 problem}.
 @end itemize
diff --git a/doc/glibc-headers/utmp.texi b/doc/glibc-headers/utmp.texi
index d7d1091e14..1e9d3757cb 100644
--- a/doc/glibc-headers/utmp.texi
+++ b/doc/glibc-headers/utmp.texi
@@ -31,4 +31,17 @@ FreeBSD 8.0, OpenBSD 7.2.
 
 Portability problems not fixed by Gnulib:
 @itemize
+@item
+On some platforms, this API does not support timestamps past the
+year 2038:
+glibc 2.38 on 32-bit platforms like x86 and ARM where @code{time_t}
+was historically 32 bits.
+@item
+On some platforms, this header misbehaves if the @code{year2038} or
+@code{year2038-recommended} modules are used and the program is
+configured without the @option{--disable-year2038} option.
+The 

bug#64937: "who" reports funny dates

2023-07-29 Thread Pádraig Brady

On 29/07/2023 17:41, Sven Joachim wrote:

A 32-bit "who" program reports funny login dates:

,
| $ file src/who
| src/who: ELF 32-bit LSB pie executable, Intel 80386, version 1 (SYSV), 
dynamically linked, interpreter /lib/ld-linux.so.2, 
BuildID[sha1]=a897e4f7a6dfd45c9245594e3d0b20497472c66d, for GNU/Linux 3.2.0, 
with debug_info, not stripped
| $ src/who
| sven tty1 133589088-06-27 20:29
| sven pts/0121346977-03-14 05:00 (:0)
| sven tty2 50067723-10-30 01:10
| sven pts/13442548-06-12 17:26 (:0)
`

This is with current coreutils git (commit 3cb862ce5f1) configured with
"CC=gcc -m32" on Debian sid/amd64, but the same issue can also be seen
on plain i386.  Originally reported by Jakub Wilk in
https://bugs.debian.org/1027135, and I noticed it myself after upgrading
an ancient machine to Debian 12 today.


I think this is due to the unconditional use of 64 bit time_t.
In normal 64 bit mode, glibc organizes that the time_t is 32 bit for the utmp 
records,
however it doesn't do this in 32 bit mode, assuming that time_t is 32 bit.

If one configures with --disable-year2038, then 32 bit time_t is used in 32 bit 
mode,
and the problem is avoided. However that's a big hammer, disabling 64 bit 
time_t everywhere.

I tried a quick build with -D__WORDSIZE_TIME64_COMPAT32=1
which is what glibc uses to force the smaller time types.
However that didn't fix the issue, so I'll need to look a bit more,
and how to get only utmp access restricted to 32 bit types.

Note there was a related query recently to move away from the utmp
interface entirely, since it is currently restricted to 32 bit times,
and so will have year 2038 issues.

cheers,
Pádraig.





bug#64937: "who" reports funny dates

2023-07-29 Thread Sven Joachim
A 32-bit "who" program reports funny login dates:

,
| $ file src/who
| src/who: ELF 32-bit LSB pie executable, Intel 80386, version 1 (SYSV), 
dynamically linked, interpreter /lib/ld-linux.so.2, 
BuildID[sha1]=a897e4f7a6dfd45c9245594e3d0b20497472c66d, for GNU/Linux 3.2.0, 
with debug_info, not stripped
| $ src/who
| sven tty1 133589088-06-27 20:29
| sven pts/0121346977-03-14 05:00 (:0)
| sven tty2 50067723-10-30 01:10
| sven pts/13442548-06-12 17:26 (:0)
`

This is with current coreutils git (commit 3cb862ce5f1) configured with
"CC=gcc -m32" on Debian sid/amd64, but the same issue can also be seen
on plain i386.  Originally reported by Jakub Wilk in
https://bugs.debian.org/1027135, and I noticed it myself after upgrading
an ancient machine to Debian 12 today.