NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/56013: systat vm reports incorrect number of users, when user login/logout



>Number:         56013
>Category:       bin
>Synopsis:       systat vm reports incorrect number of users, when user login/logout
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Feb 23 14:50:00 +0000 2021
>Originator:     Kouichi Hashikawa
>Release:        NetBSD-9.99.80
>Organization:
>Environment:
NetBSD 9.99.80 (GENERIC64) #0: Sat Feb 20 22:18:32 UTC 2021
 	mkrepro%mkrepro.NetBSD.org@localhost:/usr/src/sys/arch/evbarm/compile/GENERIC64

>Description:
systat vm reports incorrect number of users, when user login/logout.

o move setutxent(),setutent() to just before getutxent(),getutent().
o copy struct by memcpy.
o line 220 if ((etype & (1 << USER_PROCESS)) != 0) is always true
  (line 73 int etype = 1 << USER_PROCESS), and USER_PROCESS is for
  utmpx(defined in utmpx.h).

>How-To-Repeat:

>Fix:
diff -u src/usr.bin/who/utmpentry.c-dist src/usr.bin/who/utmpentry.c
--- utmpentry.c-dist    2019-10-06 08:35:57.000000000 +0900
+++ utmpentry.c 2021-02-23 23:08:18.109425752 +0900
@@ -95,14 +95,7 @@
        struct stat st;
        const char *sfname;
 
-       if (fname == NULL) {
-#ifdef SUPPORT_UTMPX
-               setutxent();
-#endif
-#ifdef SUPPORT_UTMP
-               setutent();
-#endif
-       } else {
+       if (fname != NULL) {
                size_t len = strlen(fname);
                if (len == 0)
                        errx(1, "Filename cannot be 0 length.");
@@ -133,9 +126,10 @@
                        what &= ~1;
                } else {
                        if (timespeccmp(&st.st_mtimespec, &utmpxtime, >))
-                           utmpxtime = st.st_mtimespec;
+                               memcpy(&utmpxtime, &st.st_mtimespec,
+                                   sizeof(struct timespec));
                        else
-                           what &= ~1;
+                               what &= ~1;
                }
        }
 #endif
@@ -147,7 +141,8 @@
                        what &= ~2;
                } else {
                        if (timespeccmp(&st.st_mtimespec, &utmptime, >))
-                               utmptime = st.st_mtimespec;
+                               memcpy(&utmptime, &st.st_mtimespec,
+                                   sizeof(struct timespec));
                        else
                                what &= ~2;
                }
@@ -204,6 +199,7 @@
 #endif
 
 #ifdef SUPPORT_UTMPX
+       setutxent();
        while ((what & 1) && (utx = getutxent()) != NULL) {
                if (fname == NULL && ((1 << utx->ut_type) & etype) == 0)
                        continue;
@@ -218,27 +214,26 @@
 #endif
 
 #ifdef SUPPORT_UTMP
-       if ((etype & (1 << USER_PROCESS)) != 0) {
-               while ((what & 2) && (ut = getutent()) != NULL) {
-                       if (fname == NULL && (*ut->ut_name == '\0' ||
-                           *ut->ut_line == '\0'))
-                               continue;
-                       /* Don't process entries that we have utmpx for */
-                       for (ep = ehead; ep != NULL; ep = ep->next) {
-                               if (strncmp(ep->line, ut->ut_line,
-                                   sizeof(ut->ut_line)) == 0)
-                                       break;
-                       }
-                       if (ep != NULL)
-                               continue;
-                       if ((ep = calloc(1, sizeof(*ep))) == NULL) {
-                               warn(NULL);
-                               return 0;
-                       }
-                       getentry(ep, ut);
-                       *nextp = ep;
-                       nextp = &(ep->next);
+       setutent();
+       while ((what & 2) && (ut = getutent()) != NULL) {
+               if (fname == NULL && (*ut->ut_name == '\0' ||
+                   *ut->ut_line == '\0'))
+                       continue;
+               /* Don't process entries that we have utmpx for */
+               for (ep = ehead; ep != NULL; ep = ep->next) {
+                       if (strncmp(ep->line, ut->ut_line,
+                           sizeof(ut->ut_line)) == 0)
+                               break;
                }
+               if (ep != NULL)
+                       continue;
+               if ((ep = calloc(1, sizeof(struct utmpentry))) == NULL) {
+                       warn(NULL);
+                       return 0;
+               }
+               getentry(ep, ut);
+               *nextp = ep;
+               nextp = &(ep->next);
        }
 #endif
        numutmp = 0;
@@ -318,7 +313,7 @@
        memcpy(e->line, up->ut_line, sizeof(up->ut_line));
        memcpy(e->host, up->ut_host, sizeof(up->ut_host));
 
-       e->tv = up->ut_tv;
+       memcpy(&e->tv, &up->ut_tv, sizeof(struct timeval));
        e->pid = up->ut_pid;
        e->term = up->ut_exit.e_termination;
        e->exit = up->ut_exit.e_exit;



Home | Main Index | Thread Index | Old Index