Re: [SC-L] temporary directories

2007-01-03 Thread David A. Wheeler
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

2007-01-03 Thread Robert C. Seacord
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

2007-01-02 Thread ljknews
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

2007-01-02 Thread Leichter, Jerry
[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

2007-01-02 Thread 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.)

 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

2007-01-02 Thread ljknews
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

2007-01-02 Thread Wietse Venema
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

2006-12-29 Thread Robert C. Seacord

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

2006-12-29 Thread ljknews
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.
___