Skip to content

removeDirectoryRecursive symlink TOCTOU #97

Open
@joeyh

Description

removeDirectoryRecursive and similar are supposed to avoid following symlinks. However, they all appear to have a TOCTOU flaw that exposes them to a race condition that could lead to deleting symlinked directory trees.

Ie, in a call removePathRecursive "foo", if foo is a directory at the stat call, and then gets replaced with a symlink before removeContentsRecursive calls listDirectory, then it will get a list of the files in the symlinked directory, and proceed to delete them.

This could be a security problem if deleting a directory that is writable by another user, or perhaps by a containerized, untrusted process that has been given write access to the directory. Security aside, this kind of race can lead to unexpected data loss, though the probability of the right sequence of events is of course lower.

I checked how rm -r (from coreutils) handles this, and it uses open with O_NOFOLLOW when opening directories, and so avoids listing the contents of directory symlinks.

I think that a similar fix could work here, if listDirectory used O_NOFOLLOW it seems it would nicely solve the problem. (It would also speed it up by avoiding needing to stat every directory it traverses.)

openDirStream does not currently have a way to pass that flag, so it would need to be patched first.

Metadata

Assignees

Labels

type: a-bugThe described behavior is not working as intended.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions