From 0b8c6b28fd2cc46491f7ce4f28220979609ea5da Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Fri, 27 Sep 2024 13:04:55 +0100 Subject: [PATCH] sysfs: disallow absolute symlinks. Signed-off-by: Nuno Cruces --- internal/sysfs/dirfs_supported.go | 6 ++++++ internal/sysfs/dirfs_test.go | 1 + 2 files changed, 7 insertions(+) diff --git a/internal/sysfs/dirfs_supported.go b/internal/sysfs/dirfs_supported.go index ff93415b9c..a949bd54dc 100644 --- a/internal/sysfs/dirfs_supported.go +++ b/internal/sysfs/dirfs_supported.go @@ -5,6 +5,7 @@ package sysfs import ( "io/fs" "os" + "path" experimentalsys "github.com/tetratelabs/wazero/experimental/sys" ) @@ -34,6 +35,11 @@ func (d *dirFS) Chmod(path string, perm fs.FileMode) experimentalsys.Errno { // Symlink implements the same method as documented on sys.FS func (d *dirFS) Symlink(oldName, link string) experimentalsys.Errno { + // Creating a symlink with an absolute path string fails with a "not permitted" error. + // https://github.com/WebAssembly/wasi-filesystem/blob/v0.2.0/path-resolution.md#symlinks + if path.IsAbs(oldName) { + return experimentalsys.EPERM + } // Note: do not resolve `oldName` relative to this dirFS. The link result is always resolved // when dereference the `link` on its usage (e.g. readlink, read, etc). // https://github.com/bytecodealliance/cap-std/blob/v1.0.4/cap-std/src/fs/dir.rs#L404-L409 diff --git a/internal/sysfs/dirfs_test.go b/internal/sysfs/dirfs_test.go index 55e5ee1090..95024cbb14 100644 --- a/internal/sysfs/dirfs_test.go +++ b/internal/sysfs/dirfs_test.go @@ -747,6 +747,7 @@ func TestDirFS_Symlink(t *testing.T) { testFS := DirFS(tmpDir) + require.EqualErrno(t, sys.EPERM, testFS.Symlink("/test.txt", "sub/test.txt")) require.EqualErrno(t, sys.EEXIST, testFS.Symlink("sub/test.txt", "sub/test.txt")) // Non-existing old name is allowed. require.EqualErrno(t, 0, testFS.Symlink("non-existing", "aa"))