> > In 2.34, the tmpnam.3 man page will include the following
> > para:
> > 
> >     Although  tmpnam(3)  generates  names  that are difficult to
> >     guess, it is nevertheless possible  that  between  the  time
> >     that  tmpnam(3)  returns  a  pathname, and the time that the
> >     program opens it, another program might create that pathnam
> >     using  open(2),  or  create it as a symbolic link.  This can
> >     lead to security holes.  To avoid  such  possibilities,  use
> >     the  open(2)  O_EXCL  flag  to open the pathname.  Or better
> >     yet, use mkstemp(3) or tmpfile(3).
> > 
> > I added similar text to temnam.3.
> > 
> > I also removed the text "POSIX dictates tmpnam(3)" from mktemp.3.
>
> I would like to propose the following additional changes.
> 
> Replace all occurances of the phrase "Never use >XXXXXX<" with "Gcc
> warns about the use of >XXXXXX<".  This applies to the following:
> 
>   mktemp
>   tmpnam
>   tempnam
> 
> This is enough of a practical reason to not use those functions, IMO;

except that some people don't use gcc.  The page explains *why*
gcc gives the message.

> the functions themselves aren't broken, just people's use or
> misunderstanding of them.  If the functions themselves shouldn't be
> used for some other reason, then let's document that.

We do document it.  The point is this: mkstemp() and tmpfile() are
preferable to the other functions in all circumstances.  Therefore
the other functions should never be used.

> This is done for mktemp, but I think the real, necessary information
> should be documented, instead of implying that 4.3BSD somehow
> generates an "insecure temporary file name".  It is true that the name
> is poor (since it is possible to need more than 26 temp files), but
> lets get the real reasons right.  "every use of mktemp() is a security
> risk."  Can we drop that?

Well, it is a risk.  What if someone comes along and changes
the code to remove an O_EXCL, not realising the security
implications.  Just use mkstemp()...

> Perhaps each function generating a name, (and not opening the file?)
> should also include some explicit mention of O_EXCL:
> 
>   Temporary files must be opened with O_EXCL, and error conditions
>   detected; to do otherwise introduces a race condition and a security
>   risk.  If a temporary file is ever removed and later reopened,
>   O_EXCL must be used again.
> 
> This applies to:
> 
>   mktemp
>   tmpnam
>   tempnam
>   ?mkdtemp
>   ?mkstemp
> 
> tmpfile seems to be the most portable; even mingw32 has it.  But, it
> doesn't expose the filename.  This is easy to work around with some
> simple loop:
> 
>   FILE *fp;
>   char buf[]="tmp99";
>   for (int i=0; i<=99; i++) {
>       int ret;
>       ret=snprintf(buf, "tmp%0d", i);
>       assert_perror();
>       if (NULL!=(fp=fopen(buf, "wx"))) {
>               if (i==99) {
>                 fprintf(stderr, "Failed to generate temp file\n");
>                 exit(EXIT_FAILURE);
>               }
> 
>               break;
>       }
>   }
> 
> BTW.  It occurs to me that using fopen(buf, "wx") is only safe if the
> "x" is recognized; if fopen ignores unknown options, you're SOL.

Yes.

> libc6 ignores unknown fopen flags, (and only processes the first 5
> mode characters), and I don't when "x" was introduced..

Looks like it was there since at least 2.0.

> Let's rehash.
> 
> tmpfile() is portable, always thread-safe, and, dare I say it, always
> secure.  Use it whenever you can; it isn't useful if you want a
> temporary *name*, though.
> 
> mkdtemp creates a directory.  It isn't provided by mingw32 (my new
> portability guage..), but it would be simple, obvious and intuitive to
> write a replacement to return the name of a directory which was just
> created by us, and NULL otherwise.
> 
> mkstemp creates a file, and returns the filename.  It isn't provided
> by mingw32.  Older libc versions didn't set the file mode in a safe
> way.
> 
> mktemp, tmpnam, and tempnam all generate filenames which you might
> carelessly pass to open(), which is guaranteed to be at least a little
> bit unsafe if you don't use O_EXCL, but secure if you do.  gcc is
> obnoxious and warns about them all anyway (though some implementations
> did stupidly limiting things, these functions themselves were not the
> source of the problem..).  

Those stupidly limiting things do matter, for portable applications.
And the use of environment variables is problematic sof set-user-ID
programs on some implementations.

> There is apparently no library function I
> can call to generate a filename.  These all suggest tmpfile as a
> replacement; while this isn't itself bad, I think it sucks that I have
> to suffer through gcc warnings for functions which could otherwise be
> useful.
> 
> There must also be some conclusion to the indirection mentioned in the
> title of this report:
> 
> "tempnam.3, mktemp.3 says to use mkstemp.3 which says to use tmpfile.3"

Yes, but that is a Debian bug.  Upstream does not say this.

> I would suggest that tempnam, mktemp, and tempnam suggest either
> function:
> 
>   "Use tmpfile or mkstemp instead".

Which is what they now do.

> And I would suggest to follow Michael's advice and not discourage the
> use of mkstemp.  

Thanks.

> Otherwise, change the existing pages to point
> directly to tmpfile.
>
> I would also suggest that the following (presently in the Debian
> .diff) is updated:
> 
> -The \fBtmpfile\fP() function generates a unique temporary filename.
> -The temporary file is then opened in binary read/write (w+b) mode.
> +The \fBtmpfile\fP() function opens a unique temporary file in binary
> +read/write (w+b) mode.
> 
> I would suggest to replace this with "a uniquely named temporary file"
>                                               ^^^^^^^^

No -- I don't agree.  As you note, we don't get to see the name.

> since the file itself will be empty and other empty files exist, even
> if not on the same host :)

It is a unique fle -- e.g., it has a different i-node.  Unique
is not just about content.

> In fact, the name itself is never exposed to the program, and is only
> visible on the filesystem during the tmpfile() call; it is unlinked
> immediately and the stream returned. 

Yes.

Cheers,

Michael
-- 
Michael Kerrisk
maintainer of Linux man pages Sections 2, 3, 4, 5, and 7 

Want to help with man page maintenance?  
Grab the latest tarball at
ftp://ftp.win.tue.nl/pub/linux-local/manpages/, 
read the HOWTOHELP file and grep the source 
files for 'FIXME'.


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to