Skip to content

mkdir_all: support dangling symlinks? #293

@cyphar

Description

@cyphar

For all of our other operations, it makes sense to reject dangling symlinks outright because they can just be treated as any other parent directory ENOENT, a regular ENOENT, or an EEXIST (in the case of mknod).

However, for Root::mkdir_all, it is in principle possible that we instead take the target of the dangling symlink and then try to mkdir that target (plus the trailing bits from the original path). However, there are four immediate concerns with this approach:

  1. This now requires us to do nested lookups of dangling symlinks, which may themselves contain dangling symlink path components. This means we may need to have something like the symlink stack emulation for openat2 (but would remove the need for the symlink stack for the O_PATH partial resolver). I'm not sure whether this is a great trade-off, as it will make openat2 lookups less efficient... And of course we will need an iteration limit for this. We also need to be careful when joining the trailing bits together to form the return value from resolve_partial.
  2. For the openat2 resolver there is a possibility of a race where the symlink is swapped after openat2 fails. I suspect this will be fine but we should probably model what possible risks there are here...
  3. Unlike all other lookups we have so far, we are now going to be doing a lookup starting from a non-root directory. For openat2 this will likely require kernel patches to be able to specify a separate cwd from the root (again, for the O_PATH resolver we can just drop the symlink stack).
  4. We still won't be able to handle symlinks that contain .. in the non-existent portion. I am a little worried that the error we will return in that case will be quite confusing to users (it will say that there is a ".." component but the component only exists in the dangling symlink).

Metadata

Metadata

Assignees

No one assigned

    Labels

    api/rootRelated to the Root API.target/runcRequirement to port runc to libpathrs.upstream/linuxDependent on upstream kernel work.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions