make -j creates temporary files for the purpose of storing shell commands -
unfortunately, it just names them /tmp/makeXXXXX where XXXXX is the PID of the
parent process. This leads to a potential DoS exploit wherein a user can guess
the PID of the make process and create symlinks to, say /etc/passwd, which
will be followed when root runs make -j, and overwritten (in practise it's
necessary to 'mine' /tmp with a thousand or so consecutive symlinks to
increase the chances of the PID landing in the range). This is of course only
possible if root runs a parallel make on a system with a malicious user, but I
still consider it a possibility.

The attached patches seem to rectify this problem - can someone please review
them?

Kris

-----
"That suit's sharper than a page of Oscar Wilde witticisms that's been
rolled up into a point, sprinkled with lemon juice and jabbed into
someone's eye"
"Wow, that's sharp!" - Ace Rimmer and the Cat, _Red Dwarf_
Index: job.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/make/job.c,v
retrieving revision 1.12
diff -u -r1.12 job.c
--- job.c       1999/02/14 22:22:42     1.12
+++ job.c       1999/05/15 12:24:19
@@ -161,13 +161,10 @@
 
 /*
  * tfile is the name of a file into which all shell commands are put. It is
- * used over by removing it before the child shell is executed. The XXXXX in
- * the string are replaced by the pid of the make process in a 5-character
- * field with leading zeroes.
+ * removed before the child shell is executed.
  */
 static char     tfile[] = TMPPAT;
 
-
 /*
  * Descriptions for various shells.
  */
@@ -1664,7 +1661,6 @@
 {
     register Job  *job;       /* new job descriptor */
     char         *argv[4];   /* Argument vector to shell */
-    static int    jobno = 0;  /* job number of catching output in a file */
     Boolean      cmdsOK;     /* true if the nodes commands were all right */
     Boolean      local;      /* Set true if the job was run locally */
     Boolean      noExec;     /* Set true if we decide not to run the job */
@@ -1871,8 +1867,7 @@
     /*
      * If we're using pipes to catch output, create the pipe by which we'll
      * get the shell's output. If we're using files, print out that we're
-     * starting a job and then set up its temporary-file name. This is just
-     * tfile with two extra digits tacked on -- jobno.
+     * starting a job and then set up its temporary-file name.
      */
     if (!compatMake || (job->flags & JOB_FIRST)) {
        if (usePipes) {
@@ -1886,9 +1881,8 @@
        } else {
            (void) fprintf(stdout, "Remaking `%s'\n", gn->name);
            (void) fflush(stdout);
-           sprintf(job->outFile, "%s%02d", tfile, jobno);
-           jobno = (jobno + 1) % 100;
-           job->outFd = open(job->outFile,O_WRONLY|O_CREAT|O_APPEND,0600);
+           strcpy(job->outFile, TMPPAT);
+           job->outFd = mkstemp(job->outFile);
            (void) fcntl(job->outFd, F_SETFD, 1);
        }
     }
@@ -2405,7 +2399,7 @@
 {
     GNode         *begin;     /* node for commands to do at the very start */
 
-    (void) sprintf(tfile, "/tmp/make%05d", getpid());
+    (void) mktemp(tfile);
 
     jobs =       Lst_Init(FALSE);
     stoppedJobs = Lst_Init(FALSE);
Index: job.h
===================================================================
RCS file: /home/ncvs/src/usr.bin/make/job.h,v
retrieving revision 1.8
diff -u -r1.8 job.h
--- job.h       1997/04/21 20:32:11     1.8
+++ job.h       1999/05/15 10:44:41
@@ -47,7 +47,7 @@
 #ifndef _JOB_H_
 #define _JOB_H_
 
-#define TMPPAT "/tmp/makeXXXXX"
+#define TMPPAT "/tmp/makeXXXXXXXX"
 
 /*
  * The SEL_ constants determine the maximum amount of time spent in select
@@ -128,7 +128,7 @@
        }           o_pipe;         /* data used when catching the output via
                                     * a pipe */
        struct {
-           char        of_outFile[sizeof(TMPPAT)+2];
+           char        of_outFile[sizeof(TMPPAT)];
                                        /* Name of file to which shell output
                                         * was rerouted */
            int         of_outFd;       /* Stream open to the output
Index: main.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/make/main.c,v
retrieving revision 1.30
diff -u -r1.30 main.c
--- main.c      1999/03/01 06:01:05     1.30
+++ main.c      1999/05/15 07:53:18
@@ -1253,7 +1253,7 @@
 }
 
 /*
- * enunlink --
+ * eunlink --
  *     Remove a file carefully, avoiding directories.
  */
 int

Reply via email to