//! Two-volume mount traversal constrained by a process root. use super::*; use os_vfs_paths::{Error as PathError, Mount, MountNamespace, PathState}; pub fn run(allocator: &mut memory::FrameAllocator) -> Result<(), &'static str> { let frames_before = allocator.remaining_pages(); let resolver = PathState::new(); let root = resolver.resolve(b"/sandbox").map_err(|_| "k1550-root")?; let first = Mount::new(resolver.resolve(b"/sandbox/veri") .map_err(|_| "k1550-first-path")?, 1) .map_err(|_| "k1550-first-mount")?; let second = Mount::new(resolver.resolve(b"/sandbox/ara") .map_err(|_| "k1550-second-path")?, 2) .map_err(|_| "k1550-second-mount")?; let mut namespace = MountNamespace::new(root, first, second) .map_err(|_| "k1550-namespace")?; { let route = namespace.chdir(b"/veri/alt") .map_err(|_| "k1550-first-route")?; if route.volume != 1 || route.relative_depth != 1 || route.path.component(2) != Some("alt") { return Err("k1550-first-result"); } } { let route = namespace.chdir(b"../../ara/alt") .map_err(|_| "k1550-cross-route")?; if route.volume != 2 || route.relative_depth != 1 || route.path.component(1) != Some("ara") || namespace.generation != 2 { return Err("k1550-cross-result"); } } let cwd = namespace.cwd; if namespace.chdir(b"../../../gizli") != Err(PathError::AboveRoot) || namespace.cwd != cwd || namespace.generation != 2 { return Err("k1550-root-escape"); } if namespace.chdir(b"/bilinmeyen") != Err(PathError::NoMount) || namespace.cwd != cwd || namespace.generation != 2 || allocator.remaining_pages() != frames_before { return Err("k1550-unmounted-route"); } write_line("TURKOS/OS/K1550-MOUNT: FIRST=1 SECOND=2 CROSS=VALID ROOT-ESCAPE=REJECTED CWD=UNCHANGED FRAMES=UNCHANGED"); Ok(()) }