diff options
author | cperciva <cperciva@FreeBSD.org> | 2006-01-11 08:02:16 +0000 |
---|---|---|
committer | cperciva <cperciva@FreeBSD.org> | 2006-01-11 08:02:16 +0000 |
commit | 140c58ca2739ba49a909c87a3c29ebc86724292b (patch) | |
tree | 7a81b7b15e028ef4d566ed7f81e8129a4aa4bf9a /contrib/texinfo/util | |
parent | 46b45ed528b253ce008188904a0946cd0f9a6372 (diff) | |
download | FreeBSD-src-140c58ca2739ba49a909c87a3c29ebc86724292b.zip FreeBSD-src-140c58ca2739ba49a909c87a3c29ebc86724292b.tar.gz |
Correct insecure temporary file usage in texindex. [06:01]
Correct insecure temporary file usage in ee. [06:02]
Correct a race condition when setting file permissions, sanitize file
names by default, and fix a buffer overflow when handling files
larger than 4GB in cpio. [06:03]
Fix an error in the handling of IP fragments in ipfw which can cause
a kernel panic. [06:04]
Security: FreeBSD-SA-06:01.texindex
Security: FreeBSD-SA-06:02.ee
Security: FreeBSD-SA-06:03.cpio
Security: FreeBSD-SA-06:04.ipfw
Diffstat (limited to 'contrib/texinfo/util')
-rw-r--r-- | contrib/texinfo/util/texindex.c | 65 |
1 files changed, 63 insertions, 2 deletions
diff --git a/contrib/texinfo/util/texindex.c b/contrib/texinfo/util/texindex.c index 569f877..0718e72 100644 --- a/contrib/texinfo/util/texindex.c +++ b/contrib/texinfo/util/texindex.c @@ -384,17 +384,33 @@ For more information about these matters, see the files named COPYING.\n")); usage (1); } +static char **tv; +static int tv_alloc; +static int tv_used; + +static int +findtempname (char *tempname) +{ + int i; + + for (i = 0; i < tv_used; i++) + if (strcmp (tv[i], tempname) == 0) + return (1); + return (0); +} + /* Return a name for temporary file COUNT. */ static char * maketempname (int count) { static char *tempbase = NULL; + char *tempname; char tempsuffix[10]; + int fd; if (!tempbase) { - int fd; tempbase = concat (tempdir, "txidxXXXXXX"); fd = mkstemp (tempbase); @@ -403,7 +419,52 @@ maketempname (int count) } sprintf (tempsuffix, ".%d", count); - return concat (tempbase, tempsuffix); + tempname = concat (tempbase, tempsuffix); + /* + * The open logic becomes a bit convoluted. If open(2) fails due to EEXIST, + * it's likely because somebody attempted to race us, or because we have + * already created this file. + */ + fd = open (tempname, O_CREAT|O_EXCL|O_WRONLY, 0600); + if (fd == -1) + { + /* + * If errno is not EEXIST, then open failed for some other reason, so + * we should terminate. If errno == EEXIST AND we didn't create this + * file, terminate. Otherwise, it's safe to say that errno == EEXIST + * because we already created it, in this event, we can just return. + */ + if (errno != EEXIST || + (errno == EEXIST && findtempname (tempname) == 0)) + pfatal_with_name (tempname); + return (tempname); + } + else if (fd > 0) + { + close (fd); + } + if (tv == NULL) + { + tv_alloc = 16; + tv = calloc (tv_alloc, sizeof (char *)); + if (tv == NULL) + { + fprintf (stderr, "calloc failed\n"); + exit (1); + } + } + else if (tv_used == tv_alloc) + { + tv_alloc += 4; + tv = realloc (tv, tv_alloc * sizeof (char *)); + if (tv == NULL) + { + fprintf (stderr, "realloc failed"); + exit (1); + } + } + tv[tv_used++] = strdup (tempname); + return tempname; } |