--- textutils-2.0.11/src/tac.c.orig Sat May 13 13:47:57 2000 +++ textutils-2.0.11/src/tac.c Thu Jan 4 14:34:23 2001 @@ -38,6 +38,7 @@ #include #include +#include #include #include #include "system.h" @@ -72,8 +73,6 @@ /* The number of bytes per atomic write. */ #define WRITESIZE 8192 -char *mktemp (); - /* The name this program was run with. */ char *program_name; @@ -424,14 +423,10 @@ tempdir = getenv ("TMPDIR"); if (tempdir == NULL) tempdir = DEFAULT_TMPDIR; - template = xmalloc (strlen (tempdir) + 11); + template = xmalloc (strlen (tempdir) + 12); } - sprintf (template, "%s/tacXXXXXX", tempdir); - tempfile = mktemp (template); - - /* Open temporary file exclusively, to foil a common - denial-of-service attack. */ - fd = open (tempfile, O_RDWR | O_CREAT | O_TRUNC | O_EXCL, 0600); + sprintf (template, "%s/tac.XXXXXX", tempdir); + fd = mkstemp (tempfile = template); if (fd == -1) error (EXIT_FAILURE, errno, "%s", tempfile); --- textutils-2.0.11/src/sort.c.orig Tue Dec 19 12:21:35 2000 +++ textutils-2.0.11/src/sort.c Sat Jan 6 17:30:26 2001 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "system.h" #include "closeout.h" @@ -355,14 +356,10 @@ } static FILE * -xtmpfopen (const char *file) +xfdopen (const char *file, int fd) { FILE *fp; - int fd; - /* Open temporary file exclusively, to foil a common - denial-of-service attack. */ - fd = open (file, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600); if (fd < 0 || (fp = fdopen (fd, "w")) == NULL) { error (0, errno, "%s", file); @@ -452,8 +449,8 @@ /* Return a name for a temporary file. */ -static char * -tempname (void) +static FILE * +tempfile (char **name) { static unsigned long sequence_number; @@ -462,27 +459,41 @@ char const *temp_dir = temp_dirs[seq % temp_dir_count]; size_t len = strlen (temp_dir); char const *slash = "/" + (len == 0 || temp_dir[len - 1] == '/'); - char *name = xmalloc (len + 1 + sizeof "sort" - 1 - + sizeof pid * CHAR_BIT / 3 + 1 - + sizeof seq * CHAR_BIT / 3 + 1); int long_file_names = NAME_MAX_IN_DIR (temp_dir) > 12; struct tempnode *node; + int fd; + FILE *fp; if (long_file_names) - sprintf (name, "%s%ssort%lu.%.5lu", temp_dir, slash, pid, seq); + { + *name = xmalloc (len + 1 + + sizeof pid * CHAR_BIT / 3 + 1 + + sizeof seq * CHAR_BIT / 3 + 1 + + sizeof "sort...XXXXXX"); + sprintf (*name, "%s%ssort.%lu.%.5lu.XXXXXX", temp_dir, slash, pid, seq); + fd = mkstemp(*name); + } else { + *name = xmalloc (len + 1 + 8 + 1 + 3 + 1); /* Make sure the file name is safe for an 8.3 filesystem. */ - sprintf (name, "%s%ss%.5d%.2d.%.3d", temp_dir, slash, + sprintf (*name, "%s%ss%.5d%.2d.%.3d", temp_dir, slash, (int) (pid % 100000), (int) (seq / 1000 % 100), (int) (seq % 1000)); + /* Open temporary file exclusively, to foil a number of attacks. + Note that this still allows for a denial-of-service attack on + sort itself. */ + fd = open (*name, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600); } + /* This will check for the case of fd == -1 and exit on any error */ + fp = xfdopen (*name, fd); + node = (struct tempnode *) xmalloc (sizeof (struct tempnode)); - node->name = name; + node->name = *name; node->next = temphead.next; temphead.next = node; - return name; + return fp; } /* Search through the list of temporary files for NAME; @@ -1763,7 +1774,7 @@ { for (j = 0; j < NMERGE; ++j) fps[j] = xfopen (files[i * NMERGE + j], "r"); - tfp = xtmpfopen (temp = tempname ()); + tfp = tempfile (&temp); mergefps (fps, NMERGE, tfp, temp); xfclose (tfp); for (j = 0; j < NMERGE; ++j) @@ -1772,7 +1783,7 @@ } for (j = 0; j < nfiles % NMERGE; ++j) fps[j] = xfopen (files[i * NMERGE + j], "r"); - tfp = xtmpfopen (temp = tempname ()); + tfp = tempfile (&temp); mergefps (fps, nfiles % NMERGE, tfp, temp); xfclose (tfp); for (j = 0; j < nfiles % NMERGE; ++j) @@ -1846,7 +1857,7 @@ else { ++n_temp_files; - tfp = xtmpfopen (temp_output = tempname ()); + tfp = tempfile ((char **)&temp_output); } for (i = 0; i < lines.used; ++i) if (!unique || i == 0 @@ -2417,8 +2428,7 @@ } in_fp = xfopen (files[i], "r"); - tmp = tempname (); - out_fp = xtmpfopen (tmp); + out_fp = tempfile (&tmp); /* FIXME: maybe use copy.c(copy) here. */ while ((cc = fread (buf, 1, sizeof buf, in_fp)) > 0) write_bytes (buf, cc, out_fp, tmp);