libpathrs
libpathrs copied to clipboard
mkdir_all() implementation
We need to have a Go-like os.MkdirAll implementation, since a lot of Go programs depend on this behaviour. In principle users could implement this manually but it's really suboptimal if done manually. Instead if we:
- "Partially resolve" the path (resolve as many components as possible).
mkdirateach of the following components (openat-ing the next one).
Then we should have a much more efficient implementation of the above.
https://github.com/cyphar/filepath-securejoin/pull/13 is a Go implementation of this, for reference. There were a couple of snags I didn't anticipate:
- To get feature parity between
openat2(RESOLVE_IN_ROOT)and our userspace emulated version, we need to emulate the handling of dangling symlinks correctly. The current implementation expands all symlinks completely and operates on them as though they were part of the original path, butopenat2treats them as atomic objects. https://github.com/cyphar/filepath-securejoin/pull/13 implements the necessary emulation using a "symlink stack". - Because you cannot currently get a handle directly from
mkdir, it is possible for the directory to be swapped with another path. Currently there are some protections in https://github.com/cyphar/filepath-securejoin/pull/13 to detect this case, but it might be worthwhile to consider whether this is something that is a useful attack or if we should just allow it. The argument against adding protections is that becausemkdir_alldoesn't care if the directory existed already, we are already comfortable with the directory being an attacker-created directory anyway.