pledge("stdio rpath wpath cpath flock getpw id tty") for setup
then play the game with "stdio rpath wpath getpw tty".

Most of the promises are needed for dealing with the score file.  The
function getscores() currently appears towards the end of the program's
lifetime and it calls setegid() and flock().

By hoisting the latest possible call to getscores() to right after
option parsing, we can drop the most powerful promises before starting
game play, at the cost of refactoring a bit.  The "getpw" promise is for
an unlikely error path in thisuser() that might be called very late.


Index: games/tetris/scores.c
===================================================================
RCS file: /cvs/src/games/tetris/scores.c,v
retrieving revision 1.12
diff -u -p -r1.12 scores.c
--- games/tetris/scores.c       16 Nov 2014 04:49:49 -0000      1.12
+++ games/tetris/scores.c       15 Nov 2015 12:28:17 -0000
@@ -73,14 +73,13 @@
 #define NUMSPOTS (MAXHISCORES + 1)
 #define        NLEVELS (MAXLEVEL + 1)
 
+extern int gotscores;
 static time_t now;
 static int nscores;
-static int gotscores;
 static struct highscore scores[NUMSPOTS];
 
 static int checkscores(struct highscore *, int);
 static int cmpscores(const void *, const void *);
-static void getscores(FILE **);
 static void printem(int, int, struct highscore *, int, const char *);
 static char *thisuser(void);
 
@@ -93,7 +92,7 @@ static char *thisuser(void);
  *
  * Note, we assume closing the stdio file releases the lock.
  */
-static void
+void
 getscores(FILE **fpp)
 {
        int sd, mint, lck, mask, i;
@@ -150,16 +149,13 @@ getscores(FILE **fpp)
 }
 
 void
-savescore(int level)
+savescore(FILE *sf, int level)
 {
        struct highscore *sp;
        int i;
        int change;
-       FILE *sf;
        const char *me;
 
-       getscores(&sf);
-       gotscores = 1;
        (void)time(&now);
 
        /*
Index: games/tetris/scores.h
===================================================================
RCS file: /cvs/src/games/tetris/scores.h,v
retrieving revision 1.6
diff -u -p -r1.6 scores.h
--- games/tetris/scores.h       16 Nov 2014 04:49:49 -0000      1.6
+++ games/tetris/scores.h       15 Nov 2015 12:28:17 -0000
@@ -49,5 +49,6 @@ struct highscore {
 #define MAXSCORES      9       /* maximum high score entries per person */
 #define        EXPIRATION      (5L * 365 * 24 * 60 * 60)
 
-void   savescore(int);
+void   getscores(FILE **);
+void   savescore(FILE *, int);
 void   showscores(int);
Index: games/tetris/tetris.c
===================================================================
RCS file: /cvs/src/games/tetris/tetris.c,v
retrieving revision 1.25
diff -u -p -r1.25 tetris.c
--- games/tetris/tetris.c       16 Nov 2014 04:49:49 -0000      1.25
+++ games/tetris/tetris.c       15 Nov 2015 12:28:17 -0000
@@ -60,6 +60,7 @@ int   Rows, Cols;
 const struct shape *curshape;
 const struct shape *nextshape;
 long   fallrate;
+int    gotscores;
 int    score;
 gid_t  gid, egid;
 char   key_msg[100];
@@ -150,6 +151,7 @@ randshape(void)
 int
 main(int argc, char *argv[])
 {
+       FILE *sf;
        int pos, c;
        char *keys;
        int level = 2;
@@ -159,6 +161,9 @@ main(int argc, char *argv[])
 
        keys = "jkl pq";
 
+       if (pledge("stdio rpath wpath cpath flock getpw id tty", NULL) == -1)
+               err(1, "pledge");
+
        gid = getgid();
        egid = getegid();
        setegid(gid);
@@ -201,6 +206,12 @@ main(int argc, char *argv[])
        if (argc)
                usage();
 
+       getscores(&sf);
+       gotscores = 1;
+
+       if (pledge("stdio rpath wpath getpw tty", NULL) == -1)
+               err(1, "pledge");
+
        fallrate = 1000000 / level;
 
        for (i = 0; i <= 5; i++) {
@@ -337,7 +348,7 @@ main(int argc, char *argv[])
                    (int)(score * level * PRE_PENALTY));
                score = score * PRE_PENALTY;
        }
-       savescore(level);
+       savescore(sf, level);
 
        printf("\nHit RETURN to see high scores, ^C to skip.\n");
 

Reply via email to