m4-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Changes to m4/doc/m4.texinfo,v [branch-1_4]


From: Eric Blake
Subject: Changes to m4/doc/m4.texinfo,v [branch-1_4]
Date: Thu, 19 Oct 2006 23:13:06 +0000

CVSROOT:        /sources/m4
Module name:    m4
Branch:         branch-1_4
Changes by:     Eric Blake <ericb>      06/10/19 23:13:05

Index: doc/m4.texinfo
===================================================================
RCS file: /sources/m4/m4/doc/m4.texinfo,v
retrieving revision 1.1.1.1.2.89
retrieving revision 1.1.1.1.2.90
diff -u -b -r1.1.1.1.2.89 -r1.1.1.1.2.90
--- doc/m4.texinfo      19 Oct 2006 16:12:46 -0000      1.1.1.1.2.89
+++ doc/m4.texinfo      19 Oct 2006 23:13:05 -0000      1.1.1.1.2.90
@@ -242,7 +242,7 @@
 * Syscmd::                      Executing simple commands
 * Esyscmd::                     Reading the output of commands
 * Sysval::                      Exit status
-* Maketemp::                    Making temporary files
+* Mkstemp::                     Making temporary files
 
 Miscellaneous builtin macros
 
@@ -4283,7 +4283,7 @@
 * Syscmd::                      Executing simple commands
 * Esyscmd::                     Reading the output of commands
 * Sysval::                      Exit status
-* Maketemp::                    Making temporary files
+* Mkstemp::                     Making temporary files
 @end menu
 
 @node Platform macros
@@ -4520,45 +4520,85 @@
 @result{}2304
 @end example
 
address@hidden Maketemp
address@hidden Mkstemp
 @section Making temporary files
 
 @cindex temporary file names
 @cindex files, names of temporary
 Commands specified to @code{syscmd} or @code{esyscmd} might need a
-temporary file, for output or for some other purpose.
-There is a builtin macro, @code{maketemp}, for making temporary file
-names:
+temporary file, for output or for some other purpose.  There is a
+builtin macro, @code{mkstemp}, for making a temporary file:
 
address@hidden Builtin maketemp (@var{template})
address@hidden Builtin mkstemp (@var{template})
address@hidden Builtin maketemp (@var{template})
 Expands to a name of a new, empty file, made from the string
 @var{template}, which should end with the string @samp{XXXXXX}.  The six
address@hidden characters are then replaced with random data, in order to make
-the file name unique.
address@hidden characters are then replaced with random characters matching
+the regular expression @samp{[a-zA-Z0-9._-]}, in order to make the file
+name unique.  If fewer than six @samp{X} characters are found at the end
+of @code{template}, the result will be longer than the template.  The
+created file will have access permissions as if by @kbd{chmod =rw,go=},
+meaning that the current umask of the @code{m4} process is taken into
+account, and at most only the current user can read and write the file.
+
+The traditional behavior, standardized by @acronym{POSIX}, is that
address@hidden merely replaces the trailing @samp{X} with the process
+id, without creating a file, and without ensuring that the resulting
+string is a unique file name.  In part, this means that using the same
address@hidden twice in the same input file will result in the same
+expansion.  This behavior is a security hole, as it is very easy for
+another process to guess the name that will be generated, and thus
+interfere with a subsequent use of @code{syscmd} trying to manipulate
+that file name.  Hence, @acronym{POSIX} has recommended that all new
+implementations of @code{m4} provide the secure @code{mkstemp} builtin,
+and that users of @code{m4} check for its existence.
 
-The macro @code{maketemp} is recognized only with parameters.
+The macros @code{mkstemp} and @code{maketemp} are recognized only with
+parameters.
 @end deffn
 
+If you try this next example, you will most likely get different output
+for the two file names, since the replacement characters are randomly
+chosen:
+
 @comment ignore
 @example
 maketemp(`/tmp/fooXXXXXX')
 @result{}/tmp/fooa07346
+ifdef(`mkstemp', `define(`maketemp', defn(`mkstemp'))',
+      `define(`mkstemp', defn(`maketemp'))dnl
+errprint(`warning: potentially insecure maketemp implementation
+')')
address@hidden
+mkstemp(`doc')
address@hidden
 @end example
 
-Traditional implementations of @code{m4} replaced the trailing @samp{X}
-sequence with the process id, without creating the file; meaning you
-only get one result no matter how many times you use maketemp on the
-same string.  As of this release, @acronym{POSIX} is considering the
-addition of a new macro @code{mkstemp} that behaves like @acronym{GNU}
address@hidden, so a future version of @acronym{GNU} M4 may have
-changes in this area.
address@hidden @acronym{GNU} extensions
+Unless you use the @option{--traditional} command line option (or
address@hidden, @pxref{Limits control, , Invoking m4}), the @acronym{GNU}
+version of @code{maketemp} is secure.  This means that using the same
+template to multiple calls will generate multiple files.  However, we
+recommend that you use the new @code{mkstemp} macro, introduced in
address@hidden M4 1.4.8, which is secure even in traditional mode.
 
 @example
+syscmd(`echo foo??????')dnl
address@hidden
 define(`file1', maketemp(`fooXXXXXX'))dnl
-define(`file2', maketemp(`fooXXXXXX'))dnl
-ifelse(file1, file2, `same', `different')
address@hidden
-syscmd(`rm 'file1 file2)
+ifelse(esyscmd(`echo foo??????'), `foo??????', `no file', `created')
address@hidden
+define(`file2', maketemp(`fooXX'))dnl
+define(`file3', mkstemp(`fooXXXXXX'))dnl
+ifelse(len(file1), len(file2), `same length', `different')
address@hidden length
+ifelse(file1, file2, `same', `different file')
address@hidden file
+ifelse(file2, file3, `same', `different file')
address@hidden file
+ifelse(file1, file3, `same', `different file')
address@hidden file
+syscmd(`rm 'file1 file2 file3)
 @result{}
 sysval
 @result{}0
@@ -5039,6 +5079,12 @@
 @item
 The destination of trace and debug output can be controlled with
 @code{debugfile} (@pxref{Debug Output}).
+
address@hidden
+The @code{maketemp} (@pxref{Mkstemp}) macro behaves like @code{mkstemp},
+creating a new file with a unique name on every invocation, rather than
+following the insecure behavior of replacing the trailing @samp{X}
+characters with the @code{m4} process id.
 @end itemize
 
 In addition to the above extensions, @acronym{GNU} @code{m4} implements the
@@ -5135,15 +5181,6 @@
 semantics.
 
 @item
address@hidden requires @code{maketemp} (@pxref{Maketemp}) to replace
-the trailing @samp{X} characters with the @code{m4} process id, giving
-the same result on identical input, without creating any files, which
-leaves the door open for a data race in which other processes can create
-a file by the same name.  @acronym{GNU} @code{m4} actually creates a temporary
-file for each invocation of @code{maketemp}, which means that the output
-of the macro is different even if the input is identical.
-
address@hidden
 @acronym{POSIX} requires @code{changequote(@var{arg})}
 (@pxref{Changequote}) to use newline as the close quote, but @acronym{GNU}
 @code{m4} uses @samp{'} as the close quote.  Meanwhile, some




reply via email to

[Prev in Thread] Current Thread [Next in Thread]