aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Percival <cperciva@FreeBSD.org>2006-01-11 08:08:08 +0000
committerColin Percival <cperciva@FreeBSD.org>2006-01-11 08:08:08 +0000
commit0676aec44c5e5c315e69dd0f4f8d700b7e488852 (patch)
treea1b388408790955fdf4d9c971388177e2441866c
parentb00fd6139fe7e0744defcb1acc1797287d31fd9d (diff)
downloadsrc-0676aec44c5e5c315e69dd0f4f8d700b7e488852.tar.gz
src-0676aec44c5e5c315e69dd0f4f8d700b7e488852.zip
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] Security: FreeBSD-SA-06:01.texindex Security: FreeBSD-SA-06:02.ee Security: FreeBSD-SA-06:03.cpio Approved by: so (cperciva)
Notes
Notes: svn path=/releng/4.11/; revision=154219
-rw-r--r--UPDATING10
-rw-r--r--contrib/cpio/copyin.c117
-rw-r--r--contrib/cpio/copyout.c22
-rw-r--r--contrib/cpio/copypass.c31
-rw-r--r--contrib/cpio/cpio.18
-rw-r--r--contrib/cpio/extern.h2
-rw-r--r--contrib/cpio/global.c4
-rw-r--r--contrib/cpio/main.c12
-rw-r--r--contrib/texinfo/util/texindex.c65
-rw-r--r--sys/conf/newvers.sh2
-rw-r--r--usr.bin/ee/ee.c34
11 files changed, 240 insertions, 67 deletions
diff --git a/UPDATING b/UPDATING
index 0f0a1637e828..53b5a4ca5f66 100644
--- a/UPDATING
+++ b/UPDATING
@@ -17,6 +17,16 @@ minimal number of processes, if possible, for that patch. For those
updates that don't have an advisory, or to be safe, you can do a full
build and install as described in the COMMON ITEMS section.
+20060111: p14 FreeBSD-SA-06:01.texindex, FreeBSD-SA-06:02.ee,
+ FreeBSD-SA-06:03.cpio
+ 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]
+
20051011: p13 FreeBSD-SA-05:21.openssl
Correct a man-in-the-middle SSL version rollback vulnerability.
diff --git a/contrib/cpio/copyin.c b/contrib/cpio/copyin.c
index c3cc7997608f..3bae0ee47768 100644
--- a/contrib/cpio/copyin.c
+++ b/contrib/cpio/copyin.c
@@ -46,6 +46,19 @@ $FreeBSD$
#define lchown chown
#endif
+# ifndef DIRECTORY_SEPARATOR
+# define DIRECTORY_SEPARATOR '/'
+# endif
+
+# ifndef ISSLASH
+# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
+# endif
+
+# ifndef FILE_SYSTEM_PREFIX_LEN
+# define FILE_SYSTEM_PREFIX_LEN(Filename) 0
+# endif
+
+
static void read_pattern_file ();
static void tape_skip_padding ();
static void defer_copyin ();
@@ -376,6 +389,54 @@ swab_array (ptr, count)
/* Current time for verbose table. */
static time_t current_time;
+/* Return a safer suffix of FILE_NAME, or "." if it has no safer
+ suffix. Check for fully specified file names and other atrocities. */
+
+static const char *
+safer_name_suffix (char const *file_name)
+{
+ char const *p;
+
+ /* Skip file system prefixes, leading file name components that contain
+ "..", and leading slashes. */
+
+ size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (file_name);
+
+ for (p = file_name + prefix_len; *p;)
+ {
+ if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2]))
+ prefix_len = p + 2 - file_name;
+
+ do
+ {
+ char c = *p++;
+ if (ISSLASH (c))
+ break;
+ }
+ while (*p);
+ }
+
+ for (p = file_name + prefix_len; ISSLASH (*p); p++)
+ continue;
+ prefix_len = p - file_name;
+
+ if (prefix_len)
+ {
+ char *prefix = alloca (prefix_len + 1);
+ memcpy (prefix, file_name, prefix_len);
+ prefix[prefix_len] = '\0';
+
+
+ error (0, 0, "Removing leading `%s' from member names", prefix);
+ }
+
+ if (!*p)
+ p = ".";
+
+ return p;
+}
+
+
/* Read the collection from standard input and create files
in the file system. */
@@ -396,6 +457,7 @@ process_copy_in ()
int in_file_des; /* Input file descriptor. */
char skip_file; /* Flag for use with patterns. */
int existing_dir; /* True if file is a dir & already exists. */
+ mode_t existing_mode;
int i; /* Loop index variable. */
char *link_name = NULL; /* Name of hard and symbolic links. */
#ifdef HPUX_CDF
@@ -494,18 +556,11 @@ process_copy_in ()
/* Do we have to ignore absolute paths, and if so, does the filename
have an absolute path? */
- if (no_abs_paths_flag && file_hdr.c_name && file_hdr.c_name [0] == '/')
+ if (!abs_paths_flag && file_hdr.c_name && file_hdr.c_name[0])
{
- char *p;
+ const char *p = safer_name_suffix (file_hdr.c_name);
- p = file_hdr.c_name;
- while (*p == '/')
- ++p;
- if (*p == '\0')
- {
- strcpy (file_hdr.c_name, ".");
- }
- else
+ if (p != file_hdr.c_name)
{
char *non_abs_name;
@@ -642,6 +697,7 @@ process_copy_in ()
we are trying to create, don't complain about
it. */
existing_dir = TRUE;
+ existing_mode = file_stat.st_mode;
}
else if (!unconditional_flag
&& file_hdr.c_mtime <= file_stat.st_mtime)
@@ -778,8 +834,6 @@ process_copy_in ()
}
copy_files_tape_to_disk (in_file_des, out_file_des, file_hdr.c_filesize);
disk_empty_output_buffer (out_file_des);
- if (close (out_file_des) < 0)
- error (0, errno, "%s", file_hdr.c_name);
if (archive_format == arf_crcascii)
{
@@ -789,13 +843,15 @@ process_copy_in ()
}
/* File is now copied; set attributes. */
if (!no_chown_flag)
- if ((chown (file_hdr.c_name,
+ if ((fchown (out_file_des,
set_owner_flag ? set_owner : file_hdr.c_uid,
set_group_flag ? set_group : file_hdr.c_gid) < 0)
&& errno != EPERM)
error (0, errno, "%s", file_hdr.c_name);
/* chown may have turned off some permissions we wanted. */
- if (chmod (file_hdr.c_name, (int) file_hdr.c_mode) < 0)
+ if (fchmod (out_file_des, (int) file_hdr.c_mode) < 0)
+ error (0, errno, "%s", file_hdr.c_name);
+ if (close (out_file_des) < 0)
error (0, errno, "%s", file_hdr.c_name);
if (retain_time_flag)
{
@@ -847,14 +903,23 @@ process_copy_in ()
cdf_flag = 1;
}
#endif
- res = mkdir (file_hdr.c_name, file_hdr.c_mode);
+ res = mkdir (file_hdr.c_name, file_hdr.c_mode & ~077);
}
else
- res = 0;
+ {
+ if (!no_chown_flag && (existing_mode & 077) != 0
+ && chmod (file_hdr.c_name, existing_mode & 07700) < 0)
+ {
+ error (0, errno, "%s: chmod", file_hdr.c_name);
+ return;
+ }
+ res = 0;
+ }
+
if (res < 0 && create_dir_flag)
{
create_all_directories (file_hdr.c_name);
- res = mkdir (file_hdr.c_name, file_hdr.c_mode);
+ res = mkdir (file_hdr.c_name, file_hdr.c_mode & ~077);
}
if (res < 0)
{
@@ -936,20 +1001,20 @@ process_copy_in ()
#ifdef CP_IFIFO
if ((file_hdr.c_mode & CP_IFMT) == CP_IFIFO)
- res = mkfifo (file_hdr.c_name, file_hdr.c_mode);
+ res = mkfifo (file_hdr.c_name, file_hdr.c_mode & ~077);
else
#endif
- res = mknod (file_hdr.c_name, file_hdr.c_mode,
+ res = mknod (file_hdr.c_name, file_hdr.c_mode & ~077,
makedev (file_hdr.c_rdev_maj, file_hdr.c_rdev_min));
if (res < 0 && create_dir_flag)
{
create_all_directories (file_hdr.c_name);
#ifdef CP_IFIFO
if ((file_hdr.c_mode & CP_IFMT) == CP_IFIFO)
- res = mkfifo (file_hdr.c_name, file_hdr.c_mode);
+ res = mkfifo (file_hdr.c_name, file_hdr.c_mode & ~077);
else
#endif
- res = mknod (file_hdr.c_name, file_hdr.c_mode,
+ res = mknod (file_hdr.c_name, file_hdr.c_mode & ~077,
makedev (file_hdr.c_rdev_maj,
file_hdr.c_rdev_min));
}
@@ -1376,18 +1441,18 @@ create_final_defers ()
continue;
}
- if (close (out_file_des) < 0)
- error (0, errno, "%s", d->header.c_name);
-
+
/* File is now copied; set attributes. */
if (!no_chown_flag)
- if ((chown (d->header.c_name,
+ if ((fchown (out_file_des,
set_owner_flag ? set_owner : d->header.c_uid,
set_group_flag ? set_group : d->header.c_gid) < 0)
&& errno != EPERM)
error (0, errno, "%s", d->header.c_name);
/* chown may have turned off some permissions we wanted. */
- if (chmod (d->header.c_name, (int) d->header.c_mode) < 0)
+ if (fchmod (out_file_des, (int) d->header.c_mode) < 0)
+ error (0, errno, "%s", d->header.c_name);
+ if (close (out_file_des) < 0)
error (0, errno, "%s", d->header.c_name);
if (retain_time_flag)
{
diff --git a/contrib/cpio/copyout.c b/contrib/cpio/copyout.c
index 39890b07ef3b..57eec8bff9cd 100644
--- a/contrib/cpio/copyout.c
+++ b/contrib/cpio/copyout.c
@@ -49,12 +49,13 @@ write_out_header (file_hdr, out_des)
{
char ascii_header[112];
char *magic_string;
+ int ret;
if (archive_format == arf_crcascii)
magic_string = "070702";
else
magic_string = "070701";
- sprintf (ascii_header,
+ ret = snprintf (ascii_header, sizeof(ascii_header),
"%6s%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx",
magic_string,
file_hdr->c_ino, file_hdr->c_mode, file_hdr->c_uid,
@@ -62,6 +63,10 @@ write_out_header (file_hdr, out_des)
file_hdr->c_filesize, file_hdr->c_dev_maj, file_hdr->c_dev_min,
file_hdr->c_rdev_maj, file_hdr->c_rdev_min, file_hdr->c_namesize,
file_hdr->c_chksum);
+ if (ret >= sizeof(ascii_header)) {
+ fprintf(stderr, "Internal overflow, aborting\n");
+ exit (1);
+ }
tape_buffered_write (ascii_header, out_des, 110L);
/* Write file name to output. */
@@ -71,6 +76,7 @@ write_out_header (file_hdr, out_des)
else if (archive_format == arf_oldascii || archive_format == arf_hpoldascii)
{
char ascii_header[78];
+ int ret;
#ifndef __MSDOS__
dev_t dev;
dev_t rdev;
@@ -112,7 +118,7 @@ write_out_header (file_hdr, out_des)
if ((file_hdr->c_ino >> 16) != 0)
error (0, 0, "%s: truncating inode number", file_hdr->c_name);
- sprintf (ascii_header,
+ ret = snprintf (ascii_header, sizeof(ascii_header),
"%06o%06o%06lo%06lo%06lo%06lo%06lo%06o%011lo%06lo%011lo",
file_hdr->c_magic & 0xFFFF, dev & 0xFFFF,
file_hdr->c_ino & 0xFFFF, file_hdr->c_mode & 0xFFFF,
@@ -120,6 +126,10 @@ write_out_header (file_hdr, out_des)
file_hdr->c_nlink & 0xFFFF, rdev & 0xFFFF,
file_hdr->c_mtime, file_hdr->c_namesize & 0xFFFF,
file_hdr->c_filesize);
+ if (ret >= sizeof(ascii_header)) {
+ fprintf(stderr, "Internal overflow, aborting\n");
+ exit (1);
+ }
tape_buffered_write (ascii_header, out_des, 76L);
/* Write file name to output. */
@@ -258,6 +268,14 @@ process_copy_out ()
file_hdr.c_dev_maj = major (file_stat.st_dev);
file_hdr.c_dev_min = minor (file_stat.st_dev);
file_hdr.c_ino = file_stat.st_ino;
+
+ /* Skip files larger than 4GB which will cause problems on
+ 64bit platforms (and just not work on 32bit). */
+ if (file_stat.st_size > 0xffffffff) {
+ error (0, 0, "%s: skipping >4GB file", input_name.ds_string);
+ continue;
+ }
+
/* For POSIX systems that don't define the S_IF macros,
we can't assume that S_ISfoo means the standard Unix
S_IFfoo bit(s) are set. So do it manually, with a
diff --git a/contrib/cpio/copypass.c b/contrib/cpio/copypass.c
index 9c27ac596348..3d245f280d61 100644
--- a/contrib/cpio/copypass.c
+++ b/contrib/cpio/copypass.c
@@ -173,18 +173,18 @@ process_copy_pass ()
disk_empty_output_buffer (out_file_des);
if (close (in_file_des) < 0)
error (0, errno, "%s", input_name.ds_string);
- if (close (out_file_des) < 0)
- error (0, errno, "%s", output_name.ds_string);
/* Set the attributes of the new file. */
if (!no_chown_flag)
- if ((chown (output_name.ds_string,
+ if ((fchown (out_file_des,
set_owner_flag ? set_owner : in_file_stat.st_uid,
set_group_flag ? set_group : in_file_stat.st_gid) < 0)
&& errno != EPERM)
error (0, errno, "%s", output_name.ds_string);
/* chown may have turned off some permissions we wanted. */
- if (chmod (output_name.ds_string, in_file_stat.st_mode) < 0)
+ if (fchmod (out_file_des, in_file_stat.st_mode) < 0)
+ error (0, errno, "%s", output_name.ds_string);
+ if (close (out_file_des) < 0)
error (0, errno, "%s", output_name.ds_string);
if (reset_time_flag)
{
@@ -223,15 +223,24 @@ process_copy_pass ()
cdf_flag = 1;
}
#endif
- res = mkdir (output_name.ds_string, in_file_stat.st_mode);
+ res = mkdir (output_name.ds_string, in_file_stat.st_mode & ~077);
}
else
- res = 0;
+ {
+ if (!no_chown_flag && (out_file_stat.st_mode & 077) != 0
+ && chmod (output_name.ds_string, out_file_stat.st_mode & 07700) < 0)
+ {
+ error (0, errno, "%s: chmod", output_name.ds_string);
+ continue;
+ }
+ res = 0;
+ }
+
if (res < 0 && create_dir_flag)
{
create_all_directories (output_name.ds_string);
- res = mkdir (output_name.ds_string, in_file_stat.st_mode);
+ res = mkdir (output_name.ds_string, in_file_stat.st_mode & ~077);
}
if (res < 0)
{
@@ -297,20 +306,20 @@ process_copy_pass ()
{
#ifdef S_ISFIFO
if (S_ISFIFO (in_file_stat.st_mode))
- res = mkfifo (output_name.ds_string, in_file_stat.st_mode);
+ res = mkfifo (output_name.ds_string, in_file_stat.st_mode & ~077);
else
#endif
- res = mknod (output_name.ds_string, in_file_stat.st_mode,
+ res = mknod (output_name.ds_string, in_file_stat.st_mode & ~077,
in_file_stat.st_rdev);
if (res < 0 && create_dir_flag)
{
create_all_directories (output_name.ds_string);
#ifdef S_ISFIFO
if (S_ISFIFO (in_file_stat.st_mode))
- res = mkfifo (output_name.ds_string, in_file_stat.st_mode);
+ res = mkfifo (output_name.ds_string, in_file_stat.st_mode & ~077);
else
#endif
- res = mknod (output_name.ds_string, in_file_stat.st_mode,
+ res = mknod (output_name.ds_string, in_file_stat.st_mode & ~077,
in_file_stat.st_rdev);
}
if (res < 0)
diff --git a/contrib/cpio/cpio.1 b/contrib/cpio/cpio.1
index b1ba4724c765..b0067c4138d2 100644
--- a/contrib/cpio/cpio.1
+++ b/contrib/cpio/cpio.1
@@ -19,7 +19,7 @@ cpio \- copy files to and from archives
[\-\-unconditional] [\-\-verbose] [\-\-block-size=blocks] [\-\-swap-halfwords]
[\-\-io-size=bytes] [\-\-pattern-file=file] [\-\-format=format]
[\-\-owner=[user][:.][group]] [\-\-no-preserve-owner] [\-\-message=message]
-[\-\-force\-local] [\-\-no\-absolute\-filenames] [\-\-sparse] [\-\-only\-verify\-crc]
+[\-\-force\-local] [\-\-absolute\-filenames] [\-\-sparse] [\-\-only\-verify\-crc]
[\-\-quiet] [\-\-help] [\-\-version] [pattern...] [< archive]
.B cpio
@@ -251,9 +251,9 @@ current volume number (starting at 1).
In the verbose table of contents listing, show numeric UID and GID
instead of translating them into names.
.TP
-.I " \-\-no-absolute-filenames"
-In copy-in mode, create all files relative to the current directory,
-even if they have an absolute file name in the archive.
+.I " \-\-absolute-filenames"
+Do not strip leading file name components that contain ".."
+and leading slashes from file names in copy-in mode
.TP
.I " \-\-no-preserve-owner"
In copy-in mode and copy-pass mode, do not change the ownership of the
diff --git a/contrib/cpio/extern.h b/contrib/cpio/extern.h
index 0e1344f64e27..2b5d84162d56 100644
--- a/contrib/cpio/extern.h
+++ b/contrib/cpio/extern.h
@@ -46,7 +46,7 @@ extern int no_chown_flag;
extern int sparse_flag;
extern int quiet_flag;
extern int only_verify_crc_flag;
-extern int no_abs_paths_flag;
+extern int abs_paths_flag;
extern int last_header_start;
extern int copy_matching_files;
diff --git a/contrib/cpio/global.c b/contrib/cpio/global.c
index 7fb66b2fa698..e633d0e8099c 100644
--- a/contrib/cpio/global.c
+++ b/contrib/cpio/global.c
@@ -98,8 +98,8 @@ int quiet_flag = FALSE;
actually extract the files. */
int only_verify_crc_flag = FALSE;
-/* If TRUE, don't use any absolute paths, prefix them by `./'. */
-int no_abs_paths_flag = FALSE;
+/* If TRUE, allow any absolute paths */
+int abs_paths_flag = FALSE;
#ifdef DEBUG_CPIO
/* If TRUE, print debugging information. */
diff --git a/contrib/cpio/main.c b/contrib/cpio/main.c
index 20829ef50e1a..1da035a5df7b 100644
--- a/contrib/cpio/main.c
+++ b/contrib/cpio/main.c
@@ -56,7 +56,7 @@ struct option long_opts[] =
{"list", 0, &table_flag, TRUE},
{"make-directories", 0, &create_dir_flag, TRUE},
{"message", 1, 0, 'M'},
- {"no-absolute-filenames", 0, 0, 136},
+ {"absolute-filenames", 0, 0, 136},
{"no-preserve-owner", 0, 0, 134},
{"nonmatching", 0, &copy_matching_files, FALSE},
{"numeric-uid-gid", 0, &numeric_uid, TRUE},
@@ -105,7 +105,7 @@ Usage: %s {-o|--create} [-0acvABLV] [-C bytes] [-H format] [-M message]\n\
[--unconditional] [--verbose] [--block-size=blocks] [--swap-halfwords]\n\
[--io-size=bytes] [--pattern-file=file] [--format=format]\n\
[--owner=[user][:.][group]] [--no-preserve-owner] [--message=message]\n\
- [--force-local] [--no-absolute-filenames] [--sparse] [--only-verify-crc]\n\
+ [--force-local] [--absolute-filenames] [--sparse] [--only-verify-crc]\n\
[--quiet] [--help] [--version] [pattern...] [< archive]\n",
program_name);
fprintf (fp, "\
@@ -266,8 +266,8 @@ crc newc odc bin ustar tar (all-caps also recognized)", optarg);
numeric_uid = TRUE;
break;
- case 136: /* --no-absolute-filenames */
- no_abs_paths_flag = TRUE;
+ case 136: /* --absolute-filenames */
+ abs_paths_flag = TRUE;
break;
case 134: /* --no-preserve-owner */
@@ -414,7 +414,7 @@ crc newc odc bin ustar tar (all-caps also recognized)", optarg);
|| retain_time_flag || no_chown_flag || set_owner_flag
|| set_group_flag || swap_bytes_flag || swap_halfwords_flag
|| (append_flag && !(archive_name || output_archive_name))
- || rename_batch_file || no_abs_paths_flag
+ || rename_batch_file || abs_paths_flag
|| input_archive_name || (archive_name && output_archive_name))
usage (stderr, 2);
if (archive_format == arf_unknown)
@@ -429,7 +429,7 @@ crc newc odc bin ustar tar (all-caps also recognized)", optarg);
if (argc - 1 != optind || archive_format != arf_unknown
|| swap_bytes_flag || swap_halfwords_flag
|| table_flag || rename_flag || append_flag
- || rename_batch_file || no_abs_paths_flag)
+ || rename_batch_file || abs_paths_flag)
usage (stderr, 2);
directory_name = argv[optind];
}
diff --git a/contrib/texinfo/util/texindex.c b/contrib/texinfo/util/texindex.c
index f63fdb5ecf27..1e296eecdc29 100644
--- a/contrib/texinfo/util/texindex.c
+++ b/contrib/texinfo/util/texindex.c
@@ -386,6 +386,21 @@ 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 *
@@ -393,11 +408,12 @@ maketempname (count)
int count;
{
static char *tempbase = NULL;
+ char *tempname;
char tempsuffix[10];
+ int fd;
if (!tempbase)
{
- int fd;
tempbase = concat (tempdir, "txidxXXXXXX");
fd = mkstemp (tempbase);
@@ -406,7 +422,52 @@ maketempname (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;
}
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 9c67a43d4225..ea9cf0af658e 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -36,7 +36,7 @@
TYPE="FreeBSD"
REVISION="4.11"
-BRANCH="RELEASE-p13"
+BRANCH="RELEASE-p14"
RELEASE="${REVISION}-${BRANCH}"
VERSION="${TYPE} ${RELEASE}"
diff --git a/usr.bin/ee/ee.c b/usr.bin/ee/ee.c
index 9058a4a64154..a1c3e70b1d79 100644
--- a/usr.bin/ee/ee.c
+++ b/usr.bin/ee/ee.c
@@ -302,7 +302,7 @@ void finish P_((void));
int quit P_((int noverify));
void edit_abort P_((int arg));
void delete_text P_((void));
-int write_file P_((char *file_name));
+int write_file P_((char *file_name, int warn_if_exists));
int search P_((int display_message));
void search_prompt P_((void));
void del_char P_((void));
@@ -1697,7 +1697,7 @@ char *cmd_str1;
cmd_str = cmd_str2 = get_string(file_write_prompt_str, TRUE);
}
tmp_file = resolve_name(cmd_str);
- write_file(tmp_file);
+ write_file(tmp_file, 1);
if (tmp_file != cmd_str)
free(tmp_file);
}
@@ -2404,7 +2404,7 @@ finish() /* prepare to exit edit session */
file_name = tmp_file;
}
- if (write_file(file_name))
+ if (write_file(file_name, 1))
{
text_changes = FALSE;
quit(0);
@@ -2481,8 +2481,9 @@ delete_text()
}
int
-write_file(file_name)
+write_file(file_name, warn_if_exists)
char *file_name;
+int warn_if_exists;
{
char cr;
char *tmp_point;
@@ -2492,7 +2493,8 @@ char *file_name;
int write_flag = TRUE;
charac = lines = 0;
- if ((in_file_name == NULL) || strcmp(in_file_name, file_name))
+ if (warn_if_exists &&
+ ((in_file_name == NULL) || strcmp(in_file_name, file_name)))
{
if ((temp_fp = fopen(file_name, "r")))
{
@@ -3734,7 +3736,7 @@ int arg;
{
string = get_string(file_write_prompt_str, TRUE);
tmp_file = resolve_name(string);
- write_file(tmp_file);
+ write_file(tmp_file, 1);
if (tmp_file != string)
free(tmp_file);
free(string);
@@ -3771,7 +3773,7 @@ int arg;
string = tmp_file;
}
}
- if (write_file(string))
+ if (write_file(string, 1))
{
in_file_name = string;
text_changes = FALSE;
@@ -4384,17 +4386,25 @@ spell_op() /* check spelling of words in the editor */
void
ispell_op()
{
- char name[128];
+ char template[128], *name;
char string[256];
- int pid;
+ int fd;
if (restrict_mode())
{
return;
}
- pid = getpid();
- sprintf(name, "/tmp/ee.%d", pid);
- if (write_file(name))
+ (void)sprintf(template, "/tmp/ee.XXXXXXXX");
+ name = mktemp(&template[0]);
+ fd = open(name, O_CREAT | O_EXCL | O_RDWR, 0600);
+ if (fd < 0) {
+ wmove(com_win, 0, 0);
+ wprintw(com_win, create_file_fail_msg, name);
+ wrefresh(com_win);
+ return;
+ }
+ close(fd);
+ if (write_file(name, 0))
{
sprintf(string, "ispell %s", name);
sh_command(string);