login: fix ut_line comparison logic

Sam James sam@gentoo.org
Thu Aug 7 21:33:21 GMT 2025


DJ Delorie <dj@redhat.com> writes:

> ut_line[] is not a string, it's a fixed-width character field,
> and may not be NUL terminated.  Thus, the use of strcmp is incorrect.
> strncmp is more appropriate as it stops at the field size.

Yes. While at least my copy of man-pages talks about "strings", a copy
of C23 makes clear that the array is only "possibly null-terminated" for
strncmp.

>
> Note that differences beyond the field size do not count here,
> as (1) this test doesn't do that, and (2) such differences are
> traditionally ignored (i.e. logins that are silently truncated to
> 8 characters, etc)
>
> While this is "only a test", we should still demonstrate the
> correct way of doing things.  Also, using strncmp avoids a
> "not a string" warning from gcc if you use -O1 or lower,
> where it can't deduce that overflow won't happen.

With one nit fixed:

Reviewed-by: Sam James <sam@gentoo.org>

>
> diff --git a/login/tst-utmp.c b/login/tst-utmp.c
> index f2dbf9415e..7d2b6d4a2c 100644
> --- a/login/tst-utmp.c
> +++ b/login/tst-utmp.c
> @@ -33,6 +33,7 @@
>  # define getutline getutxline
>  # define getutid getutxid
>  # define pututline pututxline
> +#define UT_LINESIZE __UT_LINESIZE

Space.

>  #else
>  # include <utmp.h>
>  #endif
> @@ -153,7 +154,7 @@ simulate_login (const char *line, const char *user)
>  
>    for (n = 0; n < num_entries; n++)
>      {
> -      if (strcmp (line, entry[n].ut_line) == 0
> +      if (strncmp (line, entry[n].ut_line, UT_LINESIZE) == 0
>  	  || entry[n].ut_type == DEAD_PROCESS)
>  	{
>  	  if (entry[n].ut_pid == DEAD_PROCESS)
> @@ -186,7 +187,7 @@ simulate_logout (const char *line)
>  
>    for (n = 0; n < num_entries; n++)
>      {
> -      if (strcmp (line, entry[n].ut_line) == 0)
> +      if (strncmp (line, entry[n].ut_line, UT_LINESIZE) == 0)
>  	{
>  	  entry[n].ut_type = DEAD_PROCESS;
>  	  strncpy (entry[n].ut_user, "", sizeof (entry[n].ut_user));
> @@ -230,7 +231,7 @@ check_login (const char *line)
>  
>    for (n = 0; n < num_entries; n++)
>      {
> -      if (strcmp (line, entry[n].ut_line) == 0)
> +      if (strncmp (line, entry[n].ut_line, UT_LINESIZE) == 0)
>  	{
>  	  if (memcmp (up, &entry[n], sizeof (struct utmp)))
>  	    {
> @@ -287,7 +288,7 @@ check_id (const char *id)
>  
>    for (n = 0; n < num_entries; n++)
>      {
> -      if (strcmp (id, entry[n].ut_id) == 0)
> +      if (strncmp (id, entry[n].ut_id, 4) == 0)
>  	{
>  	  if (memcmp (up, &entry[n], sizeof (struct utmp)))
>  	    {


More information about the Libc-alpha mailing list