pathrs: add "hallucination" helpers for SecureJoin magic

In order to maintain compatibility with previous releases of runc (which
permitted dangling symlinks as path components by permitting
non-existent path components to be treated like real directories) we
have to first do SecureJoin to construct a target path that is
compatible with the old behaviour but has all dangling symlinks (or
other invalid paths like ".." components after non-existent directories)
removed.

This is effectively a more generic verison of commit 3f925525b4
("rootfs: re-allow dangling symlinks in mount targets") and will let us
remove the need for open-coding SecureJoin workarounds.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
This commit is contained in:
Aleksa Sarai
2025-11-09 01:41:10 +11:00
parent 20c5a8ec4a
commit cfb74326be
4 changed files with 40 additions and 25 deletions
-12
View File
@@ -546,18 +546,6 @@ func (m *mountEntry) createOpenMountpoint(rootfs string) (Err error) {
}
dstIsFile = !fi.IsDir()
}
// In previous runc versions, we would tolerate nonsense paths with
// dangling symlinks as path components. pathrs-lite does not support
// this, so instead we have to emulate this behaviour by doing
// SecureJoin *purely to get a semi-reasonable path to use* and then we
// use pathrs-lite to operate on the path safely.
newUnsafePath, err := securejoin.SecureJoin(rootfs, unsafePath)
if err != nil {
return err
}
unsafePath = pathrs.LexicallyStripRoot(rootfs, newUnsafePath)
if dstIsFile {
dstFile, err = pathrs.CreateInRoot(rootfs, unsafePath, unix.O_CREAT|unix.O_EXCL|unix.O_NOFOLLOW, 0o644)
} else {