首页 -> 安全研究
安全研究
安全漏洞
BSD版本make程序存在/tmp"竞争条件"漏洞
发布日期:2000-01-21
更新日期:2000-01-21
受影响系统:
FreeBSD FreeBSD 3.4描述:
NetBSD NetBSD 1.4.1
OpenBSD OpenBSD 2.6
在一些BSD版本的make中存在一个漏洞,有可能导致发生所谓"竞争条件"的问题.当使用"-j"
参数时,make用一种不安全的方式与子进程通讯:"make"会将一些shell命令写到/tmp目录下
的临时文件中,然后临时文件将被子进程读取并执行.然而,make总是用同一个文件名来创建
并重用临时文件.因此如果攻击者能发现这个临时文件名,他有可能在合法命令被写入后再将
自己的命令写入这些文件中.当这些命令被子进程执行后,攻击者就可能获得执行make的用户
(甚至是root)的权限.
<* 来源: FreeBSD安全公告
FreeBSD-SA-00:01: Insecure temporary file handling in make(1)
*>
建议:
FreeBSD已经提供了补丁文件:
cd /usr/src/usr.bin/make
patch < /path/to/patch/file
make all
make install
Index: job.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/make/job.c,v
retrieving revision 1.16
diff -u -r1.16 job.c
--- job.c 1999/09/11 13:08:01 1.16
+++ job.c 2000/01/17 01:42:57
@@ -163,14 +163,6 @@
#define JOB_STOPPED 3 /* The job is stopped */
/*
- * 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 XXXXXXXXXX
- * in the string are replaced by mkstemp(3).
- */
-static char tfile[sizeof(TMPPAT)];
-
-
-/*
* Descriptions for various shells.
*/
static Shell shells[] = {
@@ -993,7 +985,7 @@
/*
* If we are aborting and the job table is now empty, we finish.
*/
- (void) eunlink(tfile);
+ (void) eunlink(job->tfile);
Finish(errors);
}
}
@@ -1668,6 +1660,7 @@
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 */
+ int tfd; /* File descriptor for temp file */
if (previous != NULL) {
previous->flags &= ~(JOB_FIRST|JOB_IGNERR|JOB_SILENT|JOB_REMOTE);
@@ -1697,6 +1690,12 @@
}
job->flags |= flags;
+ (void) strcpy(job->tfile, TMPPAT);
+ if ((tfd = mkstemp(job->tfile)) == -1)
+ Punt("cannot create temp file: %s", strerror(errno));
+ else
+ (void) close(tfd);
+
/*
* Check the commands now so any attributes from .DEFAULT have a chance
* to migrate to the node
@@ -1722,9 +1721,9 @@
DieHorribly();
}
- job->cmdFILE = fopen(tfile, "w+");
+ job->cmdFILE = fopen(job->tfile, "w+");
if (job->cmdFILE == NULL) {
- Punt("Could not open %s", tfile);
+ Punt("Could not open %s", job->tfile);
}
(void) fcntl(FILENO(job->cmdFILE), F_SETFD, 1);
/*
@@ -1830,7 +1829,7 @@
* Unlink and close the command file if we opened one
*/
if (job->cmdFILE != stdout) {
- (void) eunlink(tfile);
+ (void) eunlink(job->tfile);
if (job->cmdFILE != NULL)
(void) fclose(job->cmdFILE);
} else {
@@ -1859,7 +1858,7 @@
}
} else {
(void) fflush(job->cmdFILE);
- (void) eunlink(tfile);
+ (void) eunlink(job->tfile);
}
/*
@@ -2403,13 +2402,6 @@
* be running at once. */
{
GNode *begin; /* node for commands to do at the very start */
- int tfd;
-
- (void) strcpy(tfile, TMPPAT);
- if ((tfd = mkstemp(tfile)) == -1)
- Punt("cannot create temp file: %s", strerror(errno));
- else
- (void) close(tfd);
jobs = Lst_Init(FALSE);
stoppedJobs = Lst_Init(FALSE);
@@ -2914,7 +2906,7 @@
}
}
}
- (void) eunlink(tfile);
+ (void) eunlink(job->tfile);
}
/*
@@ -2948,7 +2940,6 @@
}
}
}
- (void) eunlink(tfile);
return(errors);
}
@@ -3024,6 +3015,7 @@
KILL(job->pid, SIGINT);
KILL(job->pid, SIGKILL);
#endif /* RMT_WANTS_SIGNALS */
+ (void) eunlink(job->tfile);
}
}
@@ -3032,7 +3024,6 @@
*/
while (waitpid((pid_t) -1, &foo, WNOHANG) > 0)
continue;
- (void) eunlink(tfile);
}
#ifdef REMOTE
Index: job.h
===================================================================
RCS file: /home/ncvs/src/usr.bin/make/job.h,v
retrieving revision 1.10
diff -u -r1.10 job.h
--- job.h 1999/08/28 01:03:31 1.10
+++ job.h 2000/01/17 01:42:31
@@ -93,6 +93,8 @@
#define JOB_BUFSIZE 1024
typedef struct Job {
int pid; /* The child's process ID */
+ char tfile[sizeof(TMPPAT)];
+ /* Temporary file to use for job */
GNode *node; /* The target the child is making */
LstNode tailCmds; /* The node of the first command to be
* saved when the job has been run */
浏览次数:6941
严重程度:0(网友投票)
绿盟科技给您安全的保障