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