(File System): In tmpnam, clarify security and use of
authorKevin Ryde <user42@zip.com.au>
Mon, 14 Feb 2005 23:37:28 +0000 (23:37 +0000)
committerKevin Ryde <user42@zip.com.au>
Mon, 14 Feb 2005 23:37:28 +0000 (23:37 +0000)
O_EXCL.  In mkstemp!, in fact posix doesn't specify permissions.

doc/ref/posix.texi

index 93dd3cc..388034c 100644 (file)
@@ -877,30 +877,39 @@ The return value is unspecified.
 @deffn {Scheme Procedure} tmpnam
 @deffnx {C Function} scm_tmpnam ()
 @cindex temporary file
-Return a name in the file system that does not match any
-existing file.  However there is no guarantee that another
-process will not create the file after @code{tmpnam} is called.
-Care should be taken if opening the file, e.g., use the
-@code{O_EXCL} open flag or use @code{mkstemp!} instead.
+Return an auto-generated name of a temporary file, a file which
+doesn't already exist.  The name includes a path, it's usually in
+@file{/tmp} but that's system dependent.
+
+Care must be taken when using @code{tmpnam}.  In between choosing the
+name and creating the file another program might use that name, or an
+attacker might even make it a symlink pointing at something important
+and causing you to overwrite that.
+
+The safe way is to create the file using @code{open} with
+@code{O_EXCL} to avoid any overwriting.  A loop can try again with
+another name if the file exists (error @code{EEXIST}).
+@code{mkstemp!} below does that.
 @end deffn
 
 @deffn {Scheme Procedure} mkstemp! tmpl
 @deffnx {C Function} scm_mkstemp (tmpl)
 @cindex temporary file
-Create a new unique file in the file system and returns a new
-buffered port open for reading and writing to the file.
+Create a new unique file in the file system and return a new buffered
+port open for reading and writing to the file.
 
-@var{tmpl} is a string specifying where the file should be
-created: it must end with @samp{XXXXXX} and will be changed in
-place to return the name of the temporary file.
+@var{tmpl} is a string specifying where the file should be created: it
+must end with @samp{XXXXXX} and those @samp{X}s will be changed in the
+string to return the name of the file.  (@code{port-filename} on the
+port also gives the name.)
 
-POSIX doesn't specify the permissions mode of the file, on a GNU
-system it's @code{#o600} (but was @code{#o666} in the past).  An
-application can use @code{chmod} to set what it wants.  For example
-@code{#o666} less @code{umask} is usual for ordinary files,
+POSIX doesn't specify the permissions mode of the file, on GNU and
+most systems it's @code{#o600}.  An application can use @code{chmod}
+to relax that if desired.  For example @code{#o666} less @code{umask},
+which is usual for ordinary file creation,
 
 @example
-(let ((port (mkstemp! (string-copy "file-XXXXXX"))))
+(let ((port (mkstemp! (string-copy "/tmp/myfile-XXXXXX"))))
   (chmod port (logand #o666 (lognot (umask))))
   ...)
 @end example