Boost logo

Boost :

Subject: Re: [boost] [filesystem] security questions
From: Vladimir Prus (vladimir_at_[hidden])
Date: 2009-02-21 12:58:55

Walter Landry wrote:

> Beman Dawes <bdawes_at_[hidden]> wrote:
>> On Fri, Feb 20, 2009 at 2:47 PM, Sergei Politov <spolitov_at_[hidden]> wrote:
>> > The sample commands sequence is:
>> > 1) open file
>> > 2) check file status (check symlink for instance)
>> > 3) process write operation
>> >
>> > Unfortunately I cannot find a way to do the same using boost::filesystem
>> > API.
>> I'm having trouble seeing how this is different from what fstream et
>> al. does under the covers, unless it is just the check file status you
>> are concerned about. Could you provide actual POSIX code for the
>> sequence of operations you would like to accomplish?
> If I recall correctly, the idea is that a program comes up with a
> temporary name. The application then opens the file and passes the
> descriptor around. This prevents hostile applications from deleting
> that file and creating a symlink in its place.

If an application has opened the file, then anybody can delete it,
and create anything in place of it. The application will still be
working with the file it originally opened, even if the name no longer
refers to it.

> So the symlink check is to make sure that no one created a symlink
> before you could open the file. I suppose that you could check for
> symlinks at the same time that you open the file. It feels slightly
> less robust, though.

Err, if you check that nobody created a symlink, and then open the file,
then somebody can create a symlynk in the window between check and open.

The right way to open temporary files is using the O_EXLC and O_CREAT flags
to open:

        If O_CREAT and O_EXCL are set, open() shall fail if the file exists. The check for the existence of
        the file and the creation of the file if it does not exist shall be atomic with respect to other
        threads executing open() naming the same filename in the same directory with O_EXCL and O_CREAT
        set. If O_EXCL and O_CREAT are set, and path names a symbolic link, open() shall fail and set errno
        to [EEXIST], regardless of the contents of the symbolic link. If O_EXCL is set and O_CREAT is not
        set, the result is undefined

And the primary problem here is that 'open' returns a file descriptor, and standard streams cannot
be constructed from a file descriptor. GCC's implementation used to allow that, but then it was
either removed or conditioned on some macro.

So, I imagine the question is:
- can boost.filesystem create temporary files, giving ofstream to them?
- can boost.filesystem create ofstream given a file descriptor

I think the answer to both questions is "no".

- Volodya

Boost list run by bdawes at, gregod at, cpdaniel at, john at