Summary
When a file inside an AllowedPaths root is a symlink whose target resolves into a different allowed root, rshell rejects the read with path escapes from parent. The sandbox should permit this access since the final target is within an allowed path.
Root Cause
rshell's AllowedPaths sandbox is backed by Go's os.Root / openat syscall. os.Root resolves symlinks atomically within a single root directory tree. A symlink whose target escapes that root is rejected — even if the target falls inside another configured allowed root.
Reproduction
$ ls -l dir2/
sym.txt -> ../dir1/file.txt
$ ./rshell --allow-all-commands --allowed-paths dir1,dir2 -c 'cat ./dir2/sym.txt'
cat: ./dir2/sym.txt: openat sym.txt: path escapes from parent
$ cat ./dir2/sym.txt # host shell — works fine
abc
Both dir1 and dir2 are in AllowedPaths, but the symlink in dir2 pointing into dir1 is rejected.
Expected Behavior
If the fully-resolved symlink target falls within any of the configured AllowedPaths roots, the read should succeed.
Related
Summary
When a file inside an
AllowedPathsroot is a symlink whose target resolves into a different allowed root, rshell rejects the read withpath escapes from parent. The sandbox should permit this access since the final target is within an allowed path.Root Cause
rshell's
AllowedPathssandbox is backed by Go'sos.Root/openatsyscall.os.Rootresolves symlinks atomically within a single root directory tree. A symlink whose target escapes that root is rejected — even if the target falls inside another configured allowed root.Reproduction
Both
dir1anddir2are inAllowedPaths, but the symlink indir2pointing intodir1is rejected.Expected Behavior
If the fully-resolved symlink target falls within any of the configured
AllowedPathsroots, the read should succeed.Related
/var/log/containers/*.logare symlinks into/var/log/pods/.