[PATCH] w: make sure utmp strings are really null terminated

"Thorsten Kukuk" <[email protected]> ("kukuk") Tue, 7 Mar 2023 11:49:05 +0100
Newsgroups gmane.linux.procps.devel
Message-ID <[email protected]>
--J2SCkAp4GZ/dPZZf
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline
Content-Transfer-Encoding: 8bit


Hello,

when I looked at w to see, how this can get the data from logind/elogind
instead of utmp, I found some errors regarding the handling of ut_user
and ut_line.

If the string has the max length for strncpy, strncpy does not null
terminate it. So the strncpy in this form is pretty useless, either
ut_user was null terminated, then is uname null terminated, too, or it
was not. In that case will uname also not be null terminated.
The patch also makes sure, that we use later the null terminated strings
for ut_user and ut_line and not this fields directly.

  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 Myers, Andrew McDonald, Martje Boudien Moerman
(HRB 36809, AG Nürnberg)

--J2SCkAp4GZ/dPZZf
Content-Type: text/x-patch; charset=us-ascii
Content-Disposition: attachment; filename="0001-w-make-sure-null-terminated-ut_-strings-are-used.patch"

From b69de37c7bc009f089c202ac9b3b4addf8fdd5b2 Mon Sep 17 00:00:00 2001
From: Thorsten Kukuk <[email protected]>
Date: Tue, 7 Mar 2023 11:42:20 +0100
Subject: [PATCH 1/1] w: make sure null terminated ut_* strings are used

strncpy does not null terminate a string if it has the maximal length.
Use always the null terminated variants for ut_user and ut_line.

Signed-off-by: Thorsten Kukuk <[email protected]>
---
 src/w.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/src/w.c b/src/w.c
index 5e878f04..80a867b9 100644
--- a/src/w.c
+++ b/src/w.c
@@ -32,8 +32,6 @@
 #include <getopt.h>
 #include <limits.h>
 #include <locale.h>
-#include <locale.h>
-#include <pwd.h>
 #include <pwd.h>
 #include <signal.h>
 #include <stdio.h>
@@ -490,9 +488,10 @@ static void showinfo(
 
     /* force NUL term for printf */
     strncpy(uname, u->ut_user, UT_NAMESIZE);
+    uname[UT_NAMESIZE] = '\0';
 
     if (formtype) {
-        printf("%-*.*s%-9.8s", userlen + 1, userlen, uname, u->ut_line);
+        printf("%-*.*s%-9.8s", userlen + 1, userlen, uname, tty + 5);
         if (from)
             print_from(u, ip_addresses, fromlen);
 #ifdef HAVE_UTMPX_H
@@ -514,8 +513,7 @@ static void showinfo(
         else
             printf("   ?   ");
     } else {
-        printf("%-*.*s%-9.8s", userlen + 1, userlen, u->ut_user,
-               u->ut_line);
+        printf("%-*.*s%-9.8s", userlen + 1, userlen, uname, tty + 5);
         if (from)
             print_from(u, ip_addresses, fromlen);
         if (*u->ut_line == ':')
-- 
2.39.2


--J2SCkAp4GZ/dPZZf--