-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 16/04/10 10:50, David Sommerseth wrote:
> On 16/04/10 10:08, Fabian Knittel wrote:
>> Hi David,
> 
>> David Sommerseth schrieb:
>>> As promised in the meeting today, a patch for hardening
>>> create_temp_filename().
> 
>> Great! :)
> 
>>> I've added more checks to what create_temp_filename() returns where it
>>> is called in addition, to make it even safer.
> 
>>> +  do {
>>>      uint8_t rndbytes[16];
>>>      const char *rndstr;
>>>  
>>> +    attempts++;
>>> +    mutex_lock_static (L_CREATE_TEMP);
>>> +    ++counter;
>>> +    mutex_unlock_static (L_CREATE_TEMP);
>>> +
>>>      prng_bytes (rndbytes, sizeof (rndbytes));
>>>      rndstr = format_hex_ex (rndbytes, sizeof (rndbytes), 40, 0, NULL, gc);
>>>      buf_printf (&fname, PACKAGE "_%s_%s.tmp", prefix, rndstr);
>>> +
>>> +    retfname = gen_path (directory, BSTR (&fname), gc);
>>> +    if( !retfname ) {
>>> +      msg (M_FATAL, "Failed to create temporary filename and path");
>>> +      return NULL;
>>> +    }
>>> +  } while ( test_file (retfname) && (attempts < 6) );
>>> +
>>> +  if( attempts > 5 ) {
>>> +    msg (M_FATAL, "Failed to create temporary file after %i attempts", 
>>> attempts);
>>> +    return NULL;
>>> +  }
>>> +
>>> +  /* Create the tempfile to avoid a race condition */
>>> +  fd = creat (retfname, S_IRUSR | S_IWUSR);
>>> +  if( fd == -1 ) {
> 
>> You'll probably want to add O_EXCL to creat()'s mode flags:
> 
>> |        O_EXCL Ensure that this call creates the file: if this flag  is
>>  speci
>> |               fied  in  conjunction with O_CREAT, and pathname already
>> exists,
>> |               then open() will fail.  The behavior of O_EXCL is
>> undefined  if
>> |               O_CREAT is not specified.
> 
>> Otherwise, there would be a race-condition between test_file() and
>> creat() and someone could create a symlink under you feet.
> 
> I honestly doubt that O_EXCL would help much, as the file will be closed
> immediately.

Actually, you might be right!  This might be useful.  But when checking
up the man pages for creat() and open(), I do get a bit confused about
the Linux implementation.  To explain this a little bit further, the man
page on Linux says:

        "O_EXCL is only supported on NFS when using NFSv3 or later on
         kernel 2.6 or later."[1]

But comparing against other (older) Linux man pages, it says:

        "O_EXCL is broken on NFS filesystems"[2]
        (== will not work when being used on NFS)

So this is a bit confusing - are they _only_ talking about NFS or not?
For SunOS[3], Solaris[4] and FreeBSD[5], it behaves as you do expect.

Further, to use O_EXCL you need to use open() instead, as creat() is on
Linux open() with the O_CREAT|O_WRONLY|O_TRUNC flags set.

I'll look more into this, as the only advantage is that if open() with
O_EXCL|O_CREAT fails if the file exists, it should be used instead.


kind regards,

David Sommerseth


[1] <http://www.kernel.org/doc/man-pages/online/pages/man2/open.2.html>
[2] <http://www.cl.cam.ac.uk/cgi-bin/manpage?2+creat>
[3] <http://wwwcgi.rdg.ac.uk:8081/cgi-bin/cgiwrap/wsi14/poplog/man/2/open>
[4]
<http://www.scribd.com/doc/4001670/Solaris-10-Reference-Manual-Collection-Man-Pages-Section-2-System-Calls>
[5] <http://www.manpages.info/freebsd/open.2.html>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iEYEARECAAYFAkvIKu0ACgkQDC186MBRfrrUpQCgl5PTn7a5B8TUgCEIk9wz5OU1
SPIAoKGdFpgeesbttaq/iI5FZykbnSs0
=uOsr
-----END PGP SIGNATURE-----

Reply via email to