> > 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]