mkstemp

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

mkstemp

Alex Queiroz
Hallo,

     The use of mkstemp for creating names for temporary files leaves
the file in the disk. Why not use tmpfile(), that removes the file
when it's closed? This way it's possible to use the name to create a
directory, for instance.

--
-alex
http://www.ventonegro.org/
Reply | Threaded
Open this post in threaded view
|

Re: mkstemp

Christian Vogler
>      The use of mkstemp for creating names for temporary files leaves
> the file in the disk. Why not use tmpfile(), that removes the file
> when it's closed? This way it's possible to use the name to create a
> directory, for instance.

Please, no. You have to rely on library guarantees for a secure
implementation. Some Unices, especially older variants, do not make such
guarantees.

See
http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/avoid-race.html

- Christian
Reply | Threaded
Open this post in threaded view
|

Re: mkstemp

Lisa Parratt

On 14 Apr 2006, at 23:23, Christian Vogler wrote:

>>      The use of mkstemp for creating names for temporary files leaves
>> the file in the disk. Why not use tmpfile(), that removes the file
>> when it's closed? This way it's possible to use the name to create a
>> directory, for instance.
>
> Please, no. You have to rely on library guarantees for a secure  
> implementation. Some Unices, especially older variants, do not make  
> such guarantees.
> See http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/ 
> avoid-race.html

Why not use neither, and implement a nice predictable function that  
does exactly what you want, rather than relying on the highly  
unreliable "standard" C library?

--
Lisa

Reply | Threaded
Open this post in threaded view
|

Re: mkstemp

Reuben Thomas-5
On Sat, 15 Apr 2006, Lisa Parratt wrote:

> Why not use neither, and implement a nice predictable function that
> does exactly what you want, rather than relying on the highly
> unreliable "standard" C library?

The C libraries in use on most desktop platforms are mature and
reliable. (If they contain bugs, report them and yea verily they shall
be fixed, although I realise this doesn't help immediately.) If you're
using an embedded system, you can often replace the vendor's C library
(and/or entire toolchain) with something tried and tested like dietlibc
or ulibc. Prefer vendors who ship source, so you can fix rather than
kludge.

Besides, mkstemp is something one is unlikely ever to implement (or even
worse, use) correctly, at least on a multi-tasking system. Creating
temporary files is a hard problem, as witness the number of different
functions for doing so on a typical POSIX-based system. Creating a
temporary filename without a file is simply not possible on such
systems: you always have a race condition.

Personally, I'd rather the Lua authors concentrated on providing a
programming language than an OS, and I suspect in any case that's what
they're going to do. Lua's using and not reimplementing the standard[1]
C library is one reason it's so versatile.

Reuben

[1] I assume your quotation of "standard" is meant to mean that many
libcs are not, not that there is no standard, right? :)

--
http://rrt.sc3d.org/ | robber, n.  a candid man of affairs (Bierce)
Reply | Threaded
Open this post in threaded view
|

Re: mkstemp

Alex Queiroz
Hallo,

On 4/15/06, Reuben Thomas <[hidden email]> wrote:
>
> Besides, mkstemp is something one is unlikely ever to implement (or even
> worse, use) correctly, at least on a multi-tasking system. Creating
> temporary files is a hard problem, as witness the number of different
> functions for doing so on a typical POSIX-based system. Creating a
> temporary filename without a file is simply not possible on such
> systems: you always have a race condition.
>

     But Lua closes the file anyway, just before returning the name.
Using mkstemp will not avoid a race condition in this case.

--
-alex
http://www.ventonegro.org/
Reply | Threaded
Open this post in threaded view
|

Re: mkstemp

Christian Vogler
On Saturday 15 April 2006 04:08 pm, Alex Queiroz wrote:
>      But Lua closes the file anyway, just before returning the name.
> Using mkstemp will not avoid a race condition in this case.

Ugh. Really? The correct usage of mkstemp would be something like this:

handle = mkstemp(filename)
chmod(handle) such that file is only readable and writable by owner
unlink(filename)
... use file ..
close(handle)

This also ensures that the file is deleted after it is closed.

I agree that if Lua uses mkstemp just to create a name, it is no better than
using tmpnam.

- Christian
Reply | Threaded
Open this post in threaded view
|

Re: mkstemp

David Given
Christian Vogler wrote:
[...]
> handle = mkstemp(filename)

    **** race condition here! If the process' umask isn't set correctly,
         another process might open the file. ****

> chmod(handle) such that file is only readable and writable by owner
> unlink(filename)
> ... use file ..
> close(handle)

tmpfile() is a better option; it's defined to do this stuff *for* you, so
you don't have to, and risk getting it wrong.

--
+- David Given --McQ-+ "If you're up against someone more intelligent
|  [hidden email]    | than you are, do something insane and let him think
| ([hidden email]) | himself to death." --- Pyanfar Chanur
+- www.cowlark.com --+
Reply | Threaded
Open this post in threaded view
|

Re: mkstemp

Christian Vogler
> > handle = mkstemp(filename)
>
>     **** race condition here! If the process' umask isn't set correctly,
>          another process might open the file. ****

Oops, right. You have to call umask first.

> tmpfile() is a better option; it's defined to do this stuff *for* you, so
> you don't have to, and risk getting it wrong.

Problem is that in some libraries it does not. :-(

So, what can one do?

- Christian
Reply | Threaded
Open this post in threaded view
|

Re: mkstemp

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

Christian Vogler wrote:
[...]
> Problem is that in some libraries it does not. :-(
>
> So, what can one do?

Complain, I'm afraid.

The only possible excuse for reinventing the wheel is if you're on a cart
that has no wheels --- and even then, you want to give people the option of
using the wheels provided rather than forcing them to use yours. tmpfile()
is in tonnes of standards, including Posix and C99, so if your platform
doesn't support it it's the *platform's* fault.

That doesn't mean to say that it's any less annoying, and that it means you
have to ship your own version just in case the platform doesn't have one or
if it's broken, but your own version should be used strictly as a last resort.

- --
+- David Given --McQ-+ "If you're up against someone more intelligent
|  [hidden email]    | than you are, do something insane and let him think
| ([hidden email]) | himself to death." --- Pyanfar Chanur
+- www.cowlark.com --+
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFEQWp2f9E0noFvlzgRAnS4AJ9rjMwJanAwkgQ+Z+xcTe9XSITUYQCgmejQ
bTWmQ5rkeT6uHIS9+oQnevI=
=erRd
-----END PGP SIGNATURE-----
Reply | Threaded
Open this post in threaded view
|

Re: mkstemp

Klaus Ripke
In reply to this post by Christian Vogler
On Sat, Apr 15, 2006 at 05:13:04PM -0400, Christian Vogler wrote:
> Oops, right. You have to call umask first.
well, you should in order to improve your chances
that all processes accessing the file are cooperative.
However, this helps only as far as other users are concerned,
not for other processes running with your account.

> Problem is that in some libraries it does not. :-(
and in others it's broken.
On some network filesystems there is no reliable way to do it.

> So, what can one do?
on posix you use open(2) with O_CREAT|O_EXCL,
which is safe with regard to cooperative processes.
For windoze there are similar options to CreateFile,
plus you can inhibit any sharing.

tmpfile(3), even if implemented correctly,
makes no guarantee as to who can access the file.


regards
Reply | Threaded
Open this post in threaded view
|

Re: mkstemp

Reuben Thomas-5
In reply to this post by Christian Vogler
On Sat, 15 Apr 2006, Christian Vogler wrote:

>> tmpfile() is a better option; it's defined to do this stuff *for* you, so
>> you don't have to, and risk getting it wrong.
>
> Problem is that in some libraries it does not. :-(
>
> So, what can one do?

One can use functions that are well-defined, and re-use well-written
implementations from open source libraries where necessary and possible.

I suggest the following simplification of the Lua I/O library:

1. io.tmpfile should use umask on POSIX systems to get proper
permissions (as mkstemp does).

2. io.tmpfile should return the name as a second return value, so that
you can have:

function io.tmpname ()
   local _, name = io.tmpfile ()
   return name
end

if you really must.

3. io.tmpname should be removed. On a multi-tasking system it's bogus,
and its use should be discouraged; on a single-tasking system it can be
replaced if it really must be, as above.

--
http://rrt.sc3d.org/ | priest, n.  an unpaid lawyer (q.v.)