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)
This commit is contained in:
parent
1fa77b7e18
commit
585f572c6c
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user