summaryrefslogtreecommitdiffstats
path: root/usr.bin/make
diff options
context:
space:
mode:
authorharti <harti@FreeBSD.org>2005-05-12 15:45:14 +0000
committerharti <harti@FreeBSD.org>2005-05-12 15:45:14 +0000
commit585f572c6c442d71cb51648c67b6228bcca58c99 (patch)
tree3529b06a315cfd04ef5613d22c52006fd0db90d5 /usr.bin/make
parent1fa77b7e182e7ad25776a514edfa84ff7c2fe50b (diff)
downloadFreeBSD-src-585f572c6c442d71cb51648c67b6228bcca58c99.zip
FreeBSD-src-585f572c6c442d71cb51648c67b6228bcca58c99.tar.gz
Do mktemp() by hand to get rid of the mktemp() warning and the
possible associated security hole. Submitted by: Max Okumoto <okumoto@ucsd.edu> (7.245)
Diffstat (limited to 'usr.bin/make')
-rw-r--r--usr.bin/make/job.c119
1 files changed, 102 insertions, 17 deletions
diff --git a/usr.bin/make/job.c b/usr.bin/make/job.c
index dcffdf5..502d387 100644
--- a/usr.bin/make/job.c
+++ b/usr.bin/make/job.c
@@ -522,6 +522,94 @@ static const char *sh_meta = "#=|^(){};&<>*?[]:$`\\\n";
static GNode *curTarg = NULL;
static GNode *ENDNode;
+/**
+ * Create a fifo file with a uniq filename, and returns a file
+ * descriptor to that fifo.
+ */
+static int
+mkfifotemp(char *template)
+{
+ char *start;
+ char *pathend;
+ char *ptr;
+ const unsigned char padchar[] =
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+ if (template[0] == '\0') {
+ errno = EINVAL; /* bad input string */
+ return (-1);
+ }
+
+ /* Find end of template string. */
+ pathend = strchr(template, '\0');
+ ptr = pathend - 1;
+
+ /*
+ * Starting from the end of the template replace spaces with 'X' in
+ * them with random characters until there are no more 'X'.
+ */
+ while (ptr >= template && *ptr == 'X') {
+ uint32_t rand_num = arc4random() % (sizeof(padchar) - 1);
+ *ptr-- = padchar[rand_num];
+ }
+ start = ptr + 1;
+
+ /* Check the target directory. */
+ for (; ptr > template; --ptr) {
+ if (*ptr == '/') {
+ struct stat sbuf;
+
+ *ptr = '\0';
+ if (stat(template, &sbuf) != 0)
+ return (-1);
+
+ if (!S_ISDIR(sbuf.st_mode)) {
+ errno = ENOTDIR;
+ return (-1);
+ }
+ *ptr = '/';
+ break;
+ }
+ }
+
+ for (;;) {
+ if (mkfifo(template, 0600) == 0) {
+ int fd;
+
+ if ((fd = open(template, O_RDWR, 0600)) < 0) {
+ unlink(template);
+ return (-1);
+ } else {
+ return (fd);
+ }
+ } else {
+ if (errno != EEXIST) {
+ return (-1);
+ }
+ }
+
+ /*
+ * If we have a collision, cycle through the space of
+ * filenames.
+ */
+ for (ptr = start;;) {
+ char *pad;
+
+ if (*ptr == '\0' || ptr == pathend)
+ return (-1);
+
+ pad = strchr(padchar, *ptr);
+ if (pad == NULL || *++pad == '\0') {
+ *ptr++ = padchar[0];
+ } else {
+ *ptr++ = *pad;
+ break;
+ }
+ }
+ }
+ /*NOTREACHED*/
+}
+
static void
catch_child(int sig __unused)
{
@@ -2549,24 +2637,20 @@ Job_Init(int maxproc)
* leader. Create the fifo, open it, write one char per
* allowed job into the pipe.
*/
- mktemp(fifoName);
- if (!mkfifo(fifoName, 0600)) {
- fifoFd = open(fifoName, O_RDWR | O_NONBLOCK, 0);
- if (fifoFd >= 0) {
- fifoMaster = 1;
- fcntl(fifoFd, F_SETFL, O_NONBLOCK);
- env = fifoName;
- setenv("MAKE_JOBS_FIFO", env, 1);
- while (maxproc-- > 0) {
- write(fifoFd, "+", 1);
- }
- /* The master make does not get a magic token */
- jobFull = TRUE;
- maxJobs = 0;
- } else {
- unlink(fifoName);
- env = NULL;
+ fifoFd = mkfifotemp(fifoName);
+ if (fifoFd < 0) {
+ env = NULL;
+ } else {
+ fifoMaster = 1;
+ fcntl(fifoFd, F_SETFL, O_NONBLOCK);
+ env = fifoName;
+ setenv("MAKE_JOBS_FIFO", env, 1);
+ while (maxproc-- > 0) {
+ write(fifoFd, "+", 1);
}
+ /* The master make does not get a magic token */
+ jobFull = TRUE;
+ maxJobs = 0;
}
} else if (env != NULL) {
@@ -3841,3 +3925,4 @@ Compat_Run(Lst *targs)
}
}
}
+
OpenPOWER on IntegriCloud