summaryrefslogtreecommitdiffstats
path: root/contrib/texinfo
diff options
context:
space:
mode:
authorcperciva <cperciva@FreeBSD.org>2006-01-11 08:02:16 +0000
committercperciva <cperciva@FreeBSD.org>2006-01-11 08:02:16 +0000
commit140c58ca2739ba49a909c87a3c29ebc86724292b (patch)
tree7a81b7b15e028ef4d566ed7f81e8129a4aa4bf9a /contrib/texinfo
parent46b45ed528b253ce008188904a0946cd0f9a6372 (diff)
downloadFreeBSD-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')
-rw-r--r--contrib/texinfo/util/texindex.c65
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;
}
OpenPOWER on IntegriCloud