Hi,

With your suggestion now it doesn't segfault anymore, but it still outputs
crazy stuff, do we really want this? Also -p still shows contents of the file
as per below:

0 serial@skoll:/usr/src/usr.sbin/ac$ obj/ac -w ./ac.c
total                            762774013172614.25
0 serial@skoll:/usr/src/usr.sbin/ac$ obj/ac -w ./ac.c -p
        opyright (c) 1994 Christopher G. 338687831669364.19
        etain the above copyright
        *     258230964833358.44
        user_list *Users = NULL;
        static  46353282047238.85
        -") == 0)
        fp = stdin;
        else if 43998158041234.41
        g second */
        yesterday++;
    for  39385397001446.54
    se it
    */
    tlp = lp;
    lp  18139557014551.83
    they came in on a pseudo-tty, t 17978822565419.97
    */
    head = log_out(head, &usr);
    0.00
    total                            762774013172614.25

What if we still add the check secs < 0 || secs > LLONG_MAX but instead of
erroring out just set secs to 0? It's the same behaviour as we have right now
if we use 'ac -w ./bogus_file user', this will call update_user with secs set
to 0L and the program won't segfault as it does if 'user' is not specified.

Thank you for the time spent looking at this as well! :)

Index: ac.c
===================================================================
RCS file: /cvs/src/usr.sbin/ac/ac.c,v
retrieving revision 1.25
diff -u -p -u -r1.25 ac.c
--- ac.c        26 Apr 2018 12:42:51 -0000      1.25
+++ ac.c        19 Aug 2018 08:26:54 -0000
@@ -29,6 +29,7 @@
 
 #include <err.h>
 #include <errno.h>
+#include <limits.h>
 #include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -171,6 +172,9 @@ update_user(struct user_list *head, char
 {
        struct user_list *up;
 
+       if (secs < 0 || secs > LLONG_MAX)
+               secs = 0;
+
        for (up = head; up != NULL; up = up->next) {
                if (strncmp(up->name, name, sizeof (up->name) - 1) == 0) {
                        up->secs += secs;
@@ -187,7 +191,8 @@ update_user(struct user_list *head, char
        if ((up = malloc(sizeof(struct user_list))) == NULL)
                err(1, "malloc");
        up->next = head;
-       strlcpy(up->name, name, sizeof (up->name));
+       strncpy(up->name, name, sizeof (up->name));
+       up->name[sizeof(up->name) - 1] = '\0';
        up->secs = secs;
        Total += secs;
        return up;
@@ -446,7 +451,8 @@ ac(FILE     *fp)
                         */
                        if (*usr.ut_name) {
                                if (strncmp(usr.ut_line, "tty", 3) != 0 ||
-                                   strchr("pqrstuvwxyzPQRST", usr.ut_line[3]) 
!= NULL ||
+                               memchr("pqrstuvwxyzPQRST", usr.ut_line[3],
+                                   sizeof("pqrstuvwxyzPQRST")) != NULL ||
                                    *usr.ut_host != '\0')
                                        head = log_in(head, &usr);
                        } else
@@ -457,7 +463,8 @@ ac(FILE     *fp)
        (void)fclose(fp);
        if (!(Flags & AC_W))
                usr.ut_time = time(NULL);
-       (void)strlcpy(usr.ut_line, "~", sizeof usr.ut_line);
+       (void)strncpy(usr.ut_line, "~", sizeof usr.ut_line);
+       usr.ut_line[sizeof(usr.ut_line) - 1] = '\0';
 
        if (Flags & AC_D) {
                ltm = localtime(&usr.ut_time);

Reply via email to