From a5b30a508c47017fa585173a2ed4535484e86200 Mon Sep 17 00:00:00 2001 From: Edoardo Vacchi Date: Thu, 24 Aug 2023 00:25:55 +0200 Subject: [PATCH] wasi: fix symlink-related issues with path handling (#1648) Signed-off-by: Edoardo Vacchi --- experimental/sys/errno.go | 3 +++ experimental/sys/syscall_errno.go | 2 ++ imports/wasi_snapshot_preview1/fs.go | 7 +++++-- imports/wasi_snapshot_preview1/fs_test.go | 4 ++-- internal/wasip1/errno.go | 2 ++ 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/experimental/sys/errno.go b/experimental/sys/errno.go index 81baadd0d9..2389494960 100644 --- a/experimental/sys/errno.go +++ b/experimental/sys/errno.go @@ -35,6 +35,7 @@ const ( ENOENT ENOSYS ENOTDIR + ERANGE ENOTEMPTY ENOTSOCK ENOTSUP @@ -79,6 +80,8 @@ func (e Errno) Error() string { return "functionality not supported" case ENOTDIR: return "not a directory or a symbolic link to a directory" + case ERANGE: + return "result too large" case ENOTEMPTY: return "directory not empty" case ENOTSOCK: diff --git a/experimental/sys/syscall_errno.go b/experimental/sys/syscall_errno.go index 23c4be9283..d28f6faa03 100644 --- a/experimental/sys/syscall_errno.go +++ b/experimental/sys/syscall_errno.go @@ -40,6 +40,8 @@ func syscallToErrno(err error) (Errno, bool) { return ENOSYS, true case syscall.ENOTDIR: return ENOTDIR, true + case syscall.ERANGE: + return ERANGE, true case syscall.ENOTEMPTY: return ENOTEMPTY, true case syscall.ENOTSOCK: diff --git a/imports/wasi_snapshot_preview1/fs.go b/imports/wasi_snapshot_preview1/fs.go index b80c14d7d5..9d28ae17b0 100644 --- a/imports/wasi_snapshot_preview1/fs.go +++ b/imports/wasi_snapshot_preview1/fs.go @@ -7,7 +7,6 @@ import ( "math" "path" "strings" - "syscall" "unsafe" "github.com/tetratelabs/wazero/api" @@ -1463,7 +1462,7 @@ func pathFilestatSetTimesFn(_ context.Context, mod api.Module, params []uint64) return preopen.Utimens(pathName, atim, mtim) } // Otherwise, we need to emulate don't follow by opening the file by path. - if f, errno := preopen.OpenFile(pathName, syscall.O_WRONLY, 0); errno != 0 { + if f, errno := preopen.OpenFile(pathName, experimentalsys.O_WRONLY, 0); errno != 0 { return errno } else { defer f.Close() @@ -1797,6 +1796,10 @@ func pathReadlinkFn(_ context.Context, mod api.Module, params []uint64) experime return errno } + if len(dst) > int(bufLen) { + return experimentalsys.ERANGE + } + if ok := mem.WriteString(buf, dst); !ok { return experimentalsys.EFAULT } diff --git a/imports/wasi_snapshot_preview1/fs_test.go b/imports/wasi_snapshot_preview1/fs_test.go index a62195502d..fc23e89753 100644 --- a/imports/wasi_snapshot_preview1/fs_test.go +++ b/imports/wasi_snapshot_preview1/fs_test.go @@ -4238,12 +4238,12 @@ func Test_pathReadlink(t *testing.T) { {expectedErrno: wasip1.ErrnoInval, bufLen: 100}, { name: "bufLen too short", - expectedErrno: wasip1.ErrnoFault, + expectedErrno: wasip1.ErrnoRange, fd: dirFD, bufLen: 10, path: destinationPath, pathLen: uint32(len(destinationPathName)), - buf: math.MaxUint32, + buf: 0, }, { name: "path past memory", diff --git a/internal/wasip1/errno.go b/internal/wasip1/errno.go index b4af415083..701c2aa4f2 100644 --- a/internal/wasip1/errno.go +++ b/internal/wasip1/errno.go @@ -296,6 +296,8 @@ func ToErrno(errno sys.Errno) Errno { return ErrnoNosys case sys.ENOTDIR: return ErrnoNotdir + case sys.ERANGE: + return ErrnoRange case sys.ENOTEMPTY: return ErrnoNotempty case sys.ENOTSOCK: