Hi,

As per tb@ and theo@ advise, on a separate diff for snake(6), getenv(3) should
have a safer NULL checking since the env var may exist but its contents may
still be null and the application can segfault. Also check for PATH_MAX since
it may pass the limits, added this one after seeing tb@ last email thanks!!

That being said, canfield(6), cfscores(6) and tetris(6) are using this not so
safe getenv(3) NULL check, so here is a patch for that and while here also
remove getpwuid(3) and friends for getlogin(2) on cfscores(6).

Index: games/canfield/canfield/canfield.c
===================================================================
RCS file: /cvs/src/games/canfield/canfield/canfield.c,v
retrieving revision 1.19
diff -u -p -u -r1.19 canfield.c
--- games/canfield/canfield/canfield.c  25 Nov 2015 16:19:05 -0000      1.19
+++ games/canfield/canfield/canfield.c  26 Nov 2015 08:47:44 -0000
@@ -45,6 +45,8 @@
 
 #include <ctype.h>
 #include <curses.h>
+#include <errno.h>
+#include <err.h>
 #include <fcntl.h>
 #include <limits.h>
 #include <signal.h>
@@ -1623,15 +1625,22 @@ instruct(void)
 void
 initall(void)
 {
-       int i;
+       int i, ret;
        char scorepath[PATH_MAX];
+       char *home;
 
        time(&acctstart);
        initdeck(deck);
-       if (!getenv("HOME"))
-               return;
-       snprintf(scorepath, sizeof(scorepath), "%s/%s", getenv("HOME"),
+
+       home = getenv("HOME");
+       if (home == NULL || *home == '\0')
+               err(1, "getenv");
+
+       ret = snprintf(scorepath, sizeof(scorepath), "%s/%s", home,
            ".cfscores");
+       if (ret < 0 || ret >= PATH_MAX)
+               errc(1, ENAMETOOLONG, "%s/%s", home, ".cfscores");
+
        dbfd = open(scorepath, O_RDWR | O_CREAT, 0644);
        if (dbfd < 0)
                return;
Index: games/canfield/cfscores/cfscores.c
===================================================================
RCS file: /cvs/src/games/canfield/cfscores/cfscores.c,v
retrieving revision 1.18
diff -u -p -u -r1.18 cfscores.c
--- games/canfield/cfscores/cfscores.c  24 Nov 2015 16:54:22 -0000      1.18
+++ games/canfield/cfscores/cfscores.c  26 Nov 2015 08:47:54 -0000
@@ -31,10 +31,10 @@
  */
 
 #include <sys/types.h>
+#include <errno.h>
 #include <err.h>
 #include <fcntl.h>
 #include <limits.h>
-#include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -54,27 +54,29 @@ struct betinfo {
 int dbfd;
 char scorepath[PATH_MAX];
 
-void   printuser(const struct passwd *, int);
+void   printuser(char *);
 
 int
 main(int argc, char *argv[])
 {
-       struct passwd *pw;
-       uid_t uid;
+       char *home, *name;
+       int ret;
        
-       if (!getenv("HOME"))
-               return;
-       snprintf(scorepath, sizeof(scorepath), "%s/%s", getenv("HOME"),
+       home = getenv("HOME");
+       if (home == NULL || *home == '\0')
+               err(1, "getenv");
+
+       ret = snprintf(scorepath, sizeof(scorepath), "%s/%s", home,
            ".cfscores");
+       if (ret < 0 || ret >= PATH_MAX)
+               errc(1, ENAMETOOLONG, "%s/%s", home, ".cfscores");
+
        dbfd = open(scorepath, O_RDONLY);
        if (dbfd < 0)
                err(2, "%s", scorepath);
 
-       setpwent();
-       uid = getuid();
-       pw = getpwuid(uid);
-
-       printuser(pw, 1);
+       name = getlogin();
+       printuser(name);
        exit(0);
 }
 
@@ -82,46 +84,41 @@ main(int argc, char *argv[])
  * print out info for specified password entry
  */
 void
-printuser(const struct passwd *pw, int printfail)
+printuser(char *name)
 {
        struct betinfo total;
        int i;
 
-       if (pw->pw_uid < 0) {
-               printf("Bad uid %u\n", pw->pw_uid);
-               return;
-       }
        i = read(dbfd, (char *)&total, sizeof(total));
        if (i < 0) {
                warn("lseek %s", scorepath);
                return;
        }
        if (i == 0 || total.hand == 0) {
-               if (printfail)
-                       printf("%s has never played canfield.\n", pw->pw_name);
+               printf("%s has never played canfield.\n", name);
                return;
        }
-       i = strlen(pw->pw_name);
+       i = strlen(name);
        printf("*----------------------*\n");
        if (total.worth >= 0) {
                if (i <= 8)
-                       printf("* Winnings for %-8s*\n", pw->pw_name);
+                       printf("* Winnings for %-8s*\n", name);
                else {
                        printf("*     Winnings for     *\n");
                        if (i <= 20)
-                               printf("* %20s *\n", pw->pw_name);
+                               printf("* %20s *\n", name);
                        else
-                               printf("%s\n", pw->pw_name);
+                               printf("%s\n", name);
                }
        } else {
                if (i <= 10)
-                       printf("* Losses for %-10s*\n", pw->pw_name);
+                       printf("* Losses for %-10s*\n", name);
                else {
                        printf("*      Losses for      *\n");
                        if (i <= 20)
-                               printf("* %20s *\n", pw->pw_name);
+                               printf("* %20s *\n", name);
                        else
-                               printf("%s\n", pw->pw_name);
+                               printf("%s\n", name);
                }
        }
        printf("*======================*\n");
Index: games/tetris/scores.c
===================================================================
RCS file: /cvs/src/games/tetris/scores.c,v
retrieving revision 1.13
diff -u -p -u -r1.13 scores.c
--- games/tetris/scores.c       17 Nov 2015 15:27:24 -0000      1.13
+++ games/tetris/scores.c       26 Nov 2015 08:48:09 -0000
@@ -94,8 +94,8 @@ static char *thisuser(void);
 static void
 getscores(FILE **fpp)
 {
-       int sd, mint, mask, i;
-       char *mstr, *human;
+       int sd, mint, mask, i, ret;
+       char *mstr, *human, *home;
        char scorepath[PATH_MAX];
        FILE *sf;
 
@@ -109,9 +109,15 @@ getscores(FILE **fpp)
                mstr = "r";
                human = "reading";
        }
-       if (!getenv("HOME"))
-               return;
-       snprintf(scorepath, sizeof(scorepath), "%s/%s", getenv("HOME"), 
".tetris.scores");
+
+       home = getenv("HOME");
+       if (home == NULL || *home == '\0')
+               err(1, "getenv");
+
+       ret = snprintf(scorepath, sizeof(scorepath), "%s/%s", home, 
".tetris.scores");
+       if (ret < 0 || ret >= PATH_MAX)
+               errc(1, ENAMETOOLONG, "%s/%s", home, ".snake.scores");
+
        sd = open(scorepath, mint, 0666);
        if (sd < 0) {
                if (fpp == NULL) {

Reply via email to