Re: [SC-L] temporary directories
Robert C. Seacord [EMAIL PROTECTED] wrote: I've seen advice here and there to use the mkdtemp() function to create temporary directories, for example: ... - David Wheeler's Secure Programming for Linux and Unix HOWTO at http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO.html mentions it may not be a good idea if tmp cleaners are in use (but this sort of suggests maybe it is ok if they are not.) (I also mention later on that there are issues with NFS. But anyway...) The mkdtemp() function generates a uniquely-named temporary directory from template. This function appears to work exactly like mktemp() works for files, except of course mktemp() has been widely discredited because of possible TOCTOU conditions and problems generating unique, unpredictable names. So my question is, why is mkdtemp() considered safe? Isn't it also susceptible to race conditions? Is there a reason why these race conditions are not at issue in this case? Or is it only considered safe because there is no alternative? mkdtemp() is safe from TOCTOU issues because the check-if-exists and creation-of-object operations are atomic. Under normal Unix/Linux semantics you can't create a directory of a given name if the given name already exists. (I guess there could be a kernel out there that gets this wrong, but I don't know of any.) open() is also safe if you use O_EXCL and O_CREAT, together, for the same reason: it forces checking and creation to be atomic. One problem is that many languages do NOT give you access directly to open(), but are only implemented using C's fopen() call... and fopen() has no standard way to implement exclusive creation. I wish that the C standard body would update the C library and add an exclusive create capability for fopen(), so that languages that build on fopen() can do so. This doesn't work on at least old versions of NFS reliably, unfortunately. I believe that's been fixed, but I have not verified that. --- David A. Wheeler ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php SC-L is hosted and moderated by KRvW Associates, LLC (http://www.KRvW.com) as a free, non-commercial service to the software security community. ___
Re: [SC-L] temporary directories
David, Thanks for the explanation of mkdtemp(). I got confused reading the man page because I wasn't expecting the function to return char *, but I guess that makes sense. I wish that the C standard body would update the C library and add an exclusive create capability for fopen(), so that languages that build on fopen() can do so. Have you looked at TR 24731-1? The latest revision is n119 at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1199.pdf Section 6.5.2.1 defines the fopen_s function. I am planning on submitting a DR against this TR to add an exclusive create capability. There are also some new tmpfile_s() and tmpnam_s() functions although I have some issues with these as well. This doesn't work on at least old versions of NFS reliably, unfortunately. I believe that's been fixed, but I have not verified that. I also believe that it was fixed (in Version 3). rCs ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php SC-L is hosted and moderated by KRvW Associates, LLC (http://www.KRvW.com) as a free, non-commercial service to the software security community. ___
Re: [SC-L] temporary directories
At 8:45 AM -0500 12/30/06, Leichter, Jerry wrote: [MJoderator: This is likely beyond the point of general interest to sc-l] Actually, I disagree, in that it seems to expose a set of vulnerabilities not known even to language implementors. On Fri, 29 Dec 2006, ljknews wrote: | But these are problems that have been solved by those who provided the | Ada implementation (ACT and Aonix come to mind for Unix), and thus are | not an issue for the high level language programmer. Presumably they do the create-the-file-and-immediately-delete-it trick. Since the file must, however briefly, have an entry in some directory. General purpose code can't make assuptions about what directories are available for writing, so pretty much has to put the entry in a known, public place - almost always /tmp or /var/tmp. Unless one does this very carefully, it's open to various attacks. (For one trivial example, there is no way to tell the open() call to *always* create a new file - you can only tell it if the file already exists, don't open it, return an error instead. The code had better check for that error and do something appropriate or it can be fooled into using a file an attacker created and already has access to.) Certainly code that does not check for errors is inadequate. The techniques for doing this are complex enough - and the attacks if you don't do it *exactly* right obscure enough - that after all these years, attacks based on insecure temporary file creation are still reported regularly. (Frankly, even though I know that these problems exist, if you were to ask me to write a secure temporary file creator right now, I wouldn't try - I'd look for some existing code, because I doubt I'd get it right.) Which is what one does when using the existing language implementation (except for the defect reported by Florian Weimer in this thread. -- Larry Kilgallen ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php SC-L is hosted and moderated by KRvW Associates, LLC (http://www.KRvW.com) as a free, non-commercial service to the software security community. ___
Re: [SC-L] temporary directories
[MJoderator: This is likely beyond the point of general interest to sc-l] On Fri, 29 Dec 2006, ljknews wrote: | Date: Fri, 29 Dec 2006 20:49:01 -0500 | From: ljknews [EMAIL PROTECTED] | To: sc-l@securecoding.org | Subject: Re: [SC-L] temporary directories | | At 6:56 PM -0500 12/29/06, Leichter, Jerry wrote: | | | Not on Unix, but I tend to use temporary names based on the Process ID | | that is executing. And of course file protection prevents malevolent | | access. | | | | But for a temporary file, I will specify a file that is not in any | | directory. I presume there is such a capability in Unix. | | You presume incorrectly. You're talking about VMS, where you can | open a file by file id. | | Actually, I was talking about using the FAB$V_TMD bit when creating | the file. The way one would get the effect of TMD on Unix is to create the file normally and, while keeping a descriptor open on it, delete it. The file will then live and be completely usable to this process or to any other process that either (a) already has it open (legitimately or because they snuck in on the race condition); (b) receives the open dexriptor by inheritance after a fork(); (c) receives the open descriptor by an explicit pass through a Unix-mode socket (a relatively little used facility). However, no one would be able to find the file through any file system entry, and no user-land code could get to it through its inode number even if it got its hands on that number. | One can argue this both ways, but on the specific matter of safe | access to temporary files, VMS code that uses FID access is much | easier to get right than Unix code that inherently has to walk | through directory trees. On the other hand, access by file id | isn't - or wasn't; it's been years since I used VMS - supported | directly by higher-level languages (though I vaguely recall that | C had a mechanism for doing it). | | In Ada invoking packagename.CREATE with a null name will do the | trick, although if your VMS experience ended before 1983 you would | not have run into that. But how to program easily against VMS V4.1 | when the latest version is VMS V8.3 is not a typical problem. I think the last VMS version I actively used was 5.4 or so. | I gather you are saying that the innards of Unix will force creation | of an unwanted directory entry on the Ada implementation of the required | null name support for packagename.CREATE . The Ada implementation | could rely on exclusive access to the file (surely Unix has that, right?) Not typically, no. (There are extensions, but standard Unix has only advisory locking - i.e., locking enforced between processes that choose to make locking calls.) | coupled with whatever Unix has that passes for the FAB$V_DLT bit to | delete the file on Close (such as at insert Unix words for image rundown). There's no direct analogue. Unix inode's are reference-counted - a directory entry is a reference. There's no explicit way to delete a file - all you can do is get rid of all the references you can. If that gets the ref count down to 0, the file will disappear eventually. (There's a separate count of open file descriptors to implement that sticks around while open semantics.) | But these are problems that have been solved by those who provided the | Ada implementation (ACT and Aonix come to mind for Unix), and thus are | not an issue for the high level language programmer. Presumably they do the create-the-file-and-immediately-delete-it trick. Since the file must, however briefly, have an entry in some directory. General purpose code can't make assuptions about what directories are available for writing, so pretty much has to put the entry in a known, public place - almost always /tmp or /var/tmp. Unless one does this very carefully, it's open to various attacks. (For one trivial example, there is no way to tell the open() call to *always* create a new file - you can only tell it if the file already exists, don't open it, return an error instead. The code had better check for that error and do something appropriate or it can be fooled into using a file an attacker created and already has access to.) The techniques for doing this are complex enough - and the attacks if you don't do it *exactly* right obscure enough - that after all these years, attacks based on insecure temporary file creation are still reported regularly. (Frankly, even though I know that these problems exist, if you were to ask me to write a secure temporary file creator right now, I wouldn't try - I'd look for some existing code, because I doubt I'd get it right.) -- Jerry | -- | Larry Kilgallen | ___ | Secure Coding mailing list (SC-L) SC-L@securecoding.org | List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l | List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] temporary directories
I gather you are saying that the innards of Unix will force creation of an unwanted directory entry on the Ada implementation of the required null name support for packagename.CREATE . The Ada implementation could rely on exclusive access to the file (surely Unix has that, right?) You can create files in a way that fails if the file already exists, using the O_EXCL flag. (Rumors have it that this won't work reliably over NFS, though, but I don't see why.) coupled with whatever Unix has that passes for the FAB$V_DLT bit to delete the file on Close (such as at insert Unix words for image rundown). You can delete open files on Unix, so you could in theory unlink it after creation. But the whole discussion is moot because existing Ada code seems to require that temporary files have names. 8-/ But these are problems that have been solved by those who provided the Ada implementation (ACT and Aonix come to mind for Unix), and thus are not an issue for the high level language programmer. AdaCore's implementation used mktemp and featured the usual race condition. ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php SC-L is hosted and moderated by KRvW Associates, LLC (http://www.KRvW.com) as a free, non-commercial service to the software security community. ___
Re: [SC-L] temporary directories
At 5:11 PM +0100 12/30/06, Florian Weimer wrote: I gather you are saying that the innards of Unix will force creation of an unwanted directory entry on the Ada implementation of the required null name support for packagename.CREATE . The Ada implementation could rely on exclusive access to the file (surely Unix has that, right?) You can create files in a way that fails if the file already exists, using the O_EXCL flag. (Rumors have it that this won't work reliably over NFS, though, but I don't see why.) coupled with whatever Unix has that passes for the FAB$V_DLT bit to delete the file on Close (such as at insert Unix words for image rundown). You can delete open files on Unix, so you could in theory unlink it after creation. But the whole discussion is moot because existing Ada code seems to require that temporary files have names. 8-/ The Ada language does not have such a requirement, and in fact has a requirement that names are _not_ required for temporary files. But these are problems that have been solved by those who provided the Ada implementation (ACT and Aonix come to mind for Unix), and thus are not an issue for the high level language programmer. AdaCore's implementation used mktemp and featured the usual race condition. Yucko !!! -- Larry Kilgallen ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php SC-L is hosted and moderated by KRvW Associates, LLC (http://www.KRvW.com) as a free, non-commercial service to the software security community. ___
Re: [SC-L] temporary directories
Florian Weimer: I gather you are saying that the innards of Unix will force creation of an unwanted directory entry on the Ada implementation of the required null name support for packagename.CREATE . The Ada implementation could rely on exclusive access to the file (surely Unix has that, right?) You can create files in a way that fails if the file already exists, using the O_EXCL flag. (Rumors have it that this won't work reliably over NFS, though, but I don't see why.) With NFS over UDP under heavy load, operations can succeed and return an error result anyway. When the server's reply is lost, the client retransmits the request. That is no problem with idempotent operations such as read or write that can be repeated an arbitrary number of times without changing the state of files. However, with non-idempotent operations such as mkdir, create, link, remove or rename, a retransmitted operation will fail (file exists, file not found). To remedy these false errors, the server maintains a cache of recent RPC replies to skip repeated operations; this RPC reply cache is finite and non-persistent across reboot. Application programmers can program around many but not all of these false errors. In particular there is no workaround for false failure of open(..O_CREAT|O_EXCL..). With the deployment of NFS over TCP these errors are less likely to happen. Wietse ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php SC-L is hosted and moderated by KRvW Associates, LLC (http://www.KRvW.com) as a free, non-commercial service to the software security community. ___
[SC-L] temporary directories
I've seen advice here and there to use the mkdtemp() function to create temporary directories, for example: - Kris Kennaway email at http://lwn.net/2000/1221/a/sec-tmp.php3 recommends them - David Wheeler's Secure Programming for Linux and Unix HOWTO at http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO.html mentions it may not be a good idea if tmp cleaners are in use (but this sort of suggests maybe it is ok if they are not.) - HP 03 Tru64 UNIX Protecting Your System Against File Name Spoofing Attacks. January 2003. http://h30097.www3.hp.com/docs/wpapers/spoof_wp/symlink_external.pdf - etc. The mkdtemp() function generates a uniquely-named temporary directory from template. This function appears to work exactly like mktemp() works for files, except of course mktemp() has been widely discredited because of possible TOCTOU conditions and problems generating unique, unpredictable names. So my question is, why is mkdtemp() considered safe? Isn't it also susceptible to race conditions? Is there a reason why these race conditions are not at issue in this case? Or is it only considered safe because there is no alternative? Thanks, rCs ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php SC-L is hosted and moderated by KRvW Associates, LLC (http://www.KRvW.com) as a free, non-commercial service to the software security community. ___
Re: [SC-L] temporary directories
At 6:56 PM -0500 12/29/06, Leichter, Jerry wrote: | Not on Unix, but I tend to use temporary names based on the Process ID | that is executing. And of course file protection prevents malevolent | access. | | But for a temporary file, I will specify a file that is not in any | directory. I presume there is such a capability in Unix. You presume incorrectly. You're talking about VMS, where you can open a file by file id. Actually, I was talking about using the FAB$V_TMD bit when creating the file. One can argue this both ways, but on the specific matter of safe access to temporary files, VMS code that uses FID access is much easier to get right than Unix code that inherently has to walk through directory trees. On the other hand, access by file id isn't - or wasn't; it's been years since I used VMS - supported directly by higher-level languages (though I vaguely recall that C had a mechanism for doing it). In Ada invoking packagename.CREATE with a null name will do the trick, although if your VMS experience ended before 1983 you would not have run into that. But how to program easily against VMS V4.1 when the latest version is VMS V8.3 is not a typical problem. I gather you are saying that the innards of Unix will force creation of an unwanted directory entry on the Ada implementation of the required null name support for packagename.CREATE . The Ada implementation could rely on exclusive access to the file (surely Unix has that, right?) coupled with whatever Unix has that passes for the FAB$V_DLT bit to delete the file on Close (such as at insert Unix words for image rundown). But these are problems that have been solved by those who provided the Ada implementation (ACT and Aonix come to mind for Unix), and thus are not an issue for the high level language programmer. -- Larry Kilgallen ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php SC-L is hosted and moderated by KRvW Associates, LLC (http://www.KRvW.com) as a free, non-commercial service to the software security community. ___