From e8800b5b250a021029f0c2f63efb1d79e3972111 Mon Sep 17 00:00:00 2001 From: Yage Hu Date: Tue, 4 Jun 2024 22:41:18 -0700 Subject: [PATCH 1/4] Fix path_symlink only works when dir mounted to / This commit fixes `path_symlink` not working when `-mount` is not supplied with a mapped directory. fixes #2228 Signed-off-by: Yage Hu --- imports/wasi_snapshot_preview1/fs.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/imports/wasi_snapshot_preview1/fs.go b/imports/wasi_snapshot_preview1/fs.go index 384036a275..b09c0a9086 100644 --- a/imports/wasi_snapshot_preview1/fs.go +++ b/imports/wasi_snapshot_preview1/fs.go @@ -1951,16 +1951,16 @@ func pathSymlinkFn(_ context.Context, mod api.Module, params []uint64) experimen return experimentalsys.EFAULT } - newPathBuf, ok := mem.Read(newPath, newPathLen) - if !ok { - return experimentalsys.EFAULT + _, newPathName, errno := atPath(fsc, mod.Memory(), fd, newPath, newPathLen) + if errno != 0 { + return errno } return dir.FS.Symlink( // Do not join old path since it's only resolved when dereference the link created here. // And the dereference result depends on the opening directory's file descriptor at that point. bufToStr(oldPathBuf), - path.Join(dir.Name, bufToStr(newPathBuf)), + newPathName, ) } From 31b2fd4fcda8c0e5d4e7011235c96fb20f3dc9ae Mon Sep 17 00:00:00 2001 From: Yage Hu Date: Wed, 5 Jun 2024 09:35:24 -0700 Subject: [PATCH 2/4] Add test case for path_symlink fix Signed-off-by: Yage Hu --- imports/wasi_snapshot_preview1/fs_test.go | 50 +++++++++++++++++++---- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/imports/wasi_snapshot_preview1/fs_test.go b/imports/wasi_snapshot_preview1/fs_test.go index 9743d74865..82b1a3b594 100644 --- a/imports/wasi_snapshot_preview1/fs_test.go +++ b/imports/wasi_snapshot_preview1/fs_test.go @@ -4525,14 +4525,46 @@ func Test_pathSymlink_errors(t *testing.T) { ok = mem.Write(link, []byte(linkName)) require.True(t, ok) - t.Run("success", func(t *testing.T) { - requireErrnoResult(t, wasip1.ErrnoSuccess, mod, wasip1.PathSymlinkName, - uint64(file), uint64(len(fileName)), uint64(fd), uint64(link), uint64(len(linkName))) - require.Contains(t, log.String(), wasip1.ErrnoName(wasip1.ErrnoSuccess)) - st, err := os.Lstat(joinPath(dirPath, linkName)) - require.NoError(t, err) - require.Equal(t, st.Mode()&os.ModeSymlink, os.ModeSymlink) - }) + success_cases := []struct { + name string + fd int32 + oldPath string + newPath string + }{ + { + name: "dir", + fd: fd, + oldPath: fileName, + newPath: linkName, + }, + { + name: "preopened root", + fd: sys.FdPreopen, + oldPath: fileName, + newPath: linkName, + }, + } + + for _, tt := range success_cases { + tc := tt + + t.Run(tc.name, func(t *testing.T) { + file := uint32(0xbb) + ok := mem.Write(file, []byte(fileName)) + require.True(t, ok) + + link := uint32(0xdd) + ok = mem.Write(link, []byte(linkName)) + require.True(t, ok) + + requireErrnoResult(t, wasip1.ErrnoSuccess, mod, wasip1.PathSymlinkName, + uint64(file), uint64(len(tc.oldPath)), uint64(tc.fd), uint64(link), uint64(len(tc.newPath))) + require.Contains(t, log.String(), wasip1.ErrnoName(wasip1.ErrnoSuccess)) + st, err := os.Lstat(joinPath(dirPath, linkName)) + require.NoError(t, err) + require.Equal(t, st.Mode()&os.ModeSymlink, os.ModeSymlink) + }) + } t.Run("errors", func(t *testing.T) { for _, tc := range []struct { @@ -4941,7 +4973,7 @@ func requireOpenFile(t *testing.T, tmpDir string, pathName string, data []byte, if readOnly { fsConfig = fsConfig.WithReadOnlyDirMount(tmpDir, "/") } else { - fsConfig = fsConfig.WithDirMount(tmpDir, "/") + fsConfig = fsConfig.WithDirMount(tmpDir, "preopen") } mod, r, log := requireProxyModule(t, wazero.NewModuleConfig().WithFSConfig(fsConfig)) From 0b0ad7e11a9dc5c816c8bfe107ad60e1f838912c Mon Sep 17 00:00:00 2001 From: Yage Hu Date: Wed, 5 Jun 2024 09:47:25 -0700 Subject: [PATCH 3/4] Fix casing Signed-off-by: Yage Hu --- imports/wasi_snapshot_preview1/fs_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imports/wasi_snapshot_preview1/fs_test.go b/imports/wasi_snapshot_preview1/fs_test.go index 82b1a3b594..35fc94e53c 100644 --- a/imports/wasi_snapshot_preview1/fs_test.go +++ b/imports/wasi_snapshot_preview1/fs_test.go @@ -4525,7 +4525,7 @@ func Test_pathSymlink_errors(t *testing.T) { ok = mem.Write(link, []byte(linkName)) require.True(t, ok) - success_cases := []struct { + successCases := []struct { name string fd int32 oldPath string @@ -4545,7 +4545,7 @@ func Test_pathSymlink_errors(t *testing.T) { }, } - for _, tt := range success_cases { + for _, tt := range successCases { tc := tt t.Run(tc.name, func(t *testing.T) { From 83770c325e200ecc19c76cda05771cb7149327c7 Mon Sep 17 00:00:00 2001 From: Yage Hu Date: Wed, 5 Jun 2024 09:49:29 -0700 Subject: [PATCH 4/4] Fix path_symlink test name Signed-off-by: Yage Hu --- imports/wasi_snapshot_preview1/fs_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imports/wasi_snapshot_preview1/fs_test.go b/imports/wasi_snapshot_preview1/fs_test.go index 35fc94e53c..dad5a9650a 100644 --- a/imports/wasi_snapshot_preview1/fs_test.go +++ b/imports/wasi_snapshot_preview1/fs_test.go @@ -4497,7 +4497,7 @@ func Test_pathRemoveDirectory_Errors(t *testing.T) { } } -func Test_pathSymlink_errors(t *testing.T) { +func Test_pathSymlink(t *testing.T) { tmpDir := t.TempDir() // open before loop to ensure no locking problems. dirName := "dir"