Re:Re: [boost] Serialization and tmpnam

[1] As does the manpage say: "Never use this function".
Depending on the version, you may even see a more helpful message in the manpage.
BUGS Never use this function. Use mkstemp(3) instead.
Well, not helpful enough. Making a stream from a file descriptor is code I don't have. Robert Ramey.

Le mar 20/07/2004 à 08:06, Vladimir Prus a écrit :
No, using mkstemp this way is no different than using tmpnam. Even if the file is already open, there is no reason for it to still be linked in the directory. So you may end up with a different file, and chaos ensues. Regards, Guillaume

On Tue, Jul 20, 2004 at 08:34:05AM +0200, Guillaume Melquiond wrote:
Isn't that a bit too general? If the file is in a directory that is only writeable to you then only the superuser can unlink it, and if you don't trust root you've got far bigger problems than this. If you can ensure the files are created in a directory that is not group- or world-writeable, or in a directory that has the sticky bit set, then isn't it (relatively) safe to use: char filename[] = "DIR/tmp.XXXXXX"; const int fd = mkstemp(filename); if (fd == -1) throw ...; std::fstream f(filename); ? It's certainly better than predictable names in predictable directories, right? jon -- "That which needs to be proved cannot be worth much." - Nietzsche

In article <20040720091531.GA34513@compsoc.man.ac.uk>, Jonathan Wakely <cow@compsoc.man.ac.uk> wrote:
There is no way to atomically create a directory. The only atomic filesystem modification is file creation; this property of filesystems on UNIX/POSIX is widely known and has numerous consequences, including the use of lock files to implement persistent advisory locking, and many convolutions involving secure temporary files. The only secure way to use temporary files is to have a function which securely and atomically creates and opens one and returns you the file descriptor, and to use that file descriptor (and not the path/name to the new temporary file) to access the file thereafter. This causes problems because there is no standard way to convert a file descriptor to an iostream (although most vendors have vendor extensions that allow you to do so). This alone should probably be abstracted away in boost, as it's a common request, but even if it isn't, it has to be used for secure temporary files. There is no way around it. meeroh (Yes, I know that it's possible that some filesystems have atomic directory creation. POSIX API semantics don't guarantee it because not all filesystems have that, so it's moot.) -- If this message helped you, consider buying an item from my wish list: <http://web.meeroh.org/wishlist>

On Tue, Jul 20, 2004 at 05:45:35AM -0400, Miro Jurisic wrote:
Yes, I appreciate that, but if the temp files are created in an existing directory (say, part of the CVS sandbox) that has the right permissions then there's no need to create a directory, so it's not a problem that you can't do so safely. "Doctor, doctor, when I create directories it causes a race condition." "Don't create directories then" The tests could check that the directory where temp files will be created has suitable permissions and refuse to run if not (although this should be configurable for people who don't care about security - the fools! ;) I don't claim to be an expert on this, and don't know whether it's possible to use an existing directory, so I'm just thinking out loud. Apologies if I'm just adding noise.
This is a _very_ good candidate for Boost, as everyone has to rely on incompatible vendor extensions. I'd love to have time to work on it. jon -- "The tools we use have a profound (and devious!) influence on our thinking habits, and, therefore, on our thinking abilities." - Edsger Dijkstra

Jonathan Wakely wrote:
Actually, I'm not sure what it means to atomically create a directory. Yes, if you check for directory existence and then try to create it, some other process might sneak in and create the directory before you. This is the same problem as with files. But, for files, when you try to create already existing files, you might delete all content. For directory creation, the call will just fail. The docs (mkdir manpage, and also the "Single UNIX specification"), say: ERRORS EEXIST pathname already exists (not necessarily as a directory). This includes the case where pathname is a symbolic link, dangling or not. (BTW, some time ago I even argued that fs::create_directory should ignore EEXIST error). And since the directory create will have your permissions only, I don't know where the problems is. Besides, it's always possible to use /tmp
Me too :-( - Volodya

In article <cdj26s$et$1@sea.gmane.org>, Vladimir Prus <ghost@cs.msu.su> wrote:
Actually, I'm not sure what it means to atomically create a directory.
It means that if one processes is attempting directory creation and other processes are performing other filesystem operations (including directory creation, but not limited to it), then directory creation in the first process is guaranteed to completely succeed (creating a directory with the desired path and permissions and returning 0) or completely fail (returning an error and not touching the file system). This is not the case on all file systems and on those on which it is, the POSIX API does not guarantee that mkdir() is implemented to take advantage of it. meeroh -- If this message helped you, consider buying an item from my wish list: <http://web.meeroh.org/wishlist>

Miro Jurisic wrote:
I'm still at loss. Could you give some specific situations between "completely succeed" and "completely fail". Also, how does it affect temporary files? The only case which seems to be problematic is when 'mkdir' returns success but does not set the right permissions. Is it ever possible? My reading of the docs suggests otherwise. - Volodya

In article <200407211031.10815.ghost@cs.msu.su>, Vladimir Prus <ghost@cs.msu.su> wrote: [On creating a new directory for temp files to avoid security problems with temp file race conditions.]
For example, my understanding is that there are filesystems (e.g. NFS) in which it is possible for mkdir to return an error even though the directory was created, for example. That fails the "completely succeeds or completely fails" definition of atomic I am applying here. However, it is possible that my knowledge is out of date on this, and it's likely this particular failure is not relevant to temp file creation. I strongly believe that boost::filesystem should do the right thing as far as temp files are concerned, so this question boils down to whether mkdir is the right thing or not. I have not been able to find an authoritative reference either way. However, <http://www.awprofessional.com/articles/article.asp?p=23947&seqNum=5> gives a recommended procedure for creating secure temporary files and it does not involve mkdir. (Another difficulty with using mkdir for temp files is that it potentially leaves you with a directory if you "forget" to delete it because of a poorly handled exception or a crash; an unlinked file has no such danger.) meeroh -- If this message helped you, consider buying an item from my wish list: <http://web.meeroh.org/wishlist>

Miro Jurisic wrote:
If it fails even though directory is created, this is no security risk... after getting the error we'll bail out.
I strongly believe that boost::filesystem should do the right thing as far as temp files are concerned,
Agreed.
Yes, because it uses /tmp, which, as I pointed in another email, is also as secure as it can gets -- so we can use that solution at Unix. The book also says "never close and reopen the file" -- which is different from opening the file by name when you already hold an open file descriptor.
Yes, that's true. So, /tmp is best. Need to figure out what to do on Windows. - Volodya

Jonathan Wakely wrote:
I think it is.
Right.
Actually, on Unix it is safe to just use char filename[] = "/tmp/tmp.XXXXXX"; const int fd = mkstemp(filename); because it /tmp does not exist, or does not have sticky bit, the system is in trouble already. And I'm not sure it's even possible to have "/" not owned by root. - Volodya

"Robert Ramey" <ramey@rrsd.com> wrote in message news:20040720041528.C8A1C319C9@acme.west.net...
Nicolai Josuttis has written iostreams based on file descriptors: http://www.josuttis.com/cppcode/fdstream.html. Jonathan
participants (6)
-
Guillaume Melquiond
-
Jonathan Turkanis
-
Jonathan Wakely
-
Miro Jurisic
-
Robert Ramey
-
Vladimir Prus