{"record":{"id":"2f87344b2bb6730f","repo":"wasmerio/wasmer","slug":"symlinks-in-wasi-fd-read","errorCode":null,"errorMessage":"Symlinks in wasi::fd_read","messagePattern":"Symlinks in wasi::fd_read","errorType":"panic","errorClass":"panic","httpStatus":null,"severity":"error","filePath":"lib/wasix/src/syscalls/wasix/sock_send_file.rs","lineNumber":198,"sourceCode":"                                    let mut buf = vec![0u8; sub_count as usize];\n                                    let amt = virtual_fs::AsyncReadExt::read(pipe, &mut buf[..])\n                                        .await\n                                        .map_err(map_io_err)?;\n                                    buf.truncate(amt);\n                                    Ok(buf)\n                                })?);\n                                env = ctx.data();\n                                data\n                            }\n                            Kind::PipeTx { .. }\n                            | Kind::Epoll { .. }\n                            | Kind::EventNotifications { .. } => {\n                                return Ok(Err(Errno::Inval));\n                            }\n                            Kind::Dir { .. } | Kind::Root { .. } => {\n                                return Ok(Err(Errno::Isdir));\n                            }\n                            Kind::Symlink { .. } => unimplemented!(\"Symlinks in wasi::fd_read\"),\n                            Kind::Buffer { buffer } => {\n                                // TODO: optimize with MaybeUninit\n                                let mut buf = vec![0u8; sub_count as usize];\n\n                                let mut buf_read = &buffer[offset..];\n                                let amt = wasi_try_ok_ok!(\n                                    std::io::Read::read(&mut buf_read, &mut buf[..])\n                                        .map_err(map_io_err)\n                                );\n                                buf.truncate(amt);\n                                buf\n                            }\n                        }\n                    };\n\n                    fd_entry\n                        .inner\n                        .offset","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/wasmerio/wasmer/blob/8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5/lib/wasix/src/syscalls/wasix/sock_send_file.rs#L180-L216","documentation":"In wasi::fd_read (used internally by sock_send_file_internal / apply_sock_send_file), reading from an inode whose kind is Symlink hits an explicit `unimplemented!` panic. The WASEX syscall layer simply has no implementation for dereferencing symlinks when reading file contents to send over a socket, so any attempt to do so aborts the process with this panic message.","triggerScenarios":"Calling the sock_send_file / fd_read syscall path when the source handle's inode is of Kind::Symlink. This is a hard panic (process abort), not a returned Errno.","commonSituations":"Running a WASIX program that sends a file over a socket where the path in the preopened directory tree is a symlink (e.g. a symlinked log file or symlinked config inside a mapped directory). More common on host setups that use symlinks by default (macOS, Linux dotfiles).","solutions":["Replace the symlink with a real file, or point the guest at the symlink's resolved target instead.","Resolve the symlink on the host before mapping it into the sandbox (e.g. use a physical path).","If you control the runtime, implement symlink resolution (readlink + inode follow) in Kind::Symlink handling in sock_send_file.rs and return the target inode's buffer.","As a workaround, copy the file to a non-symlinked location and read/send from there."],"exampleFix":"// before\nKind::Symlink { .. } => unimplemented!(\"Symlinks in wasi::fd_read\"),\n// after (runtime-side fix idea)\nKind::Symlink { resolved, .. } => {\n    // follow to the resolved inode instead of panicking\n    self.read_inode(resolved, offset, buf)\n}","handlingStrategy":"validation","validationCode":"// before sending a file over the socket, ensure the path is not a symlink\nlet md = std::fs::symlink_metadata(path)?;\nif md.file_type().is_symlink() {\n    return Err(io::Error::new(io::ErrorKind::Unsupported, \"symlinked files not supported for sock_send_file\"));\n}","typeGuard":"fn is_regular_file(p: &Path) -> bool {\n    std::fs::symlink_metadata(p).map(|m| m.is_file()).unwrap_or(false)\n}","tryCatchPattern":null,"preventionTips":["Do not place symlinks inside directories mapped into the WASIX sandbox","Resolve symlinks on the host (canonicalize) before mounting/packaging files","Treat this as a process abort (panic), not a catchable WASI errno — pre-validate paths"],"tags":["wasix","wasi","unimplemented","symlink","panic"],"backgroundTag":"unimplemented-symlink-fd-read","analyzedSha":"8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5","analyzedAt":"2026-09-01T23:06:31.009Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}