From 809db7fc1b50a3a8f0d9ea7b1bdec10e1b7f24c3 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Wed, 3 Jan 2024 22:51:08 +0000 Subject: [PATCH] deps: update uvwasi to 0.0.20 and fixup tests - update uvwasi to 0.0.20 - adjust tests to reflect udpated behaviour from https://github.com/nodejs/uvwasi/pull/224 included in uvwasi 0.0.20 Signed-off-by: Michael Dawson --- deps/uvwasi/include/uvwasi.h | 2 +- deps/uvwasi/src/path_resolver.c | 118 +++++++++++++++++++++++------ deps/uvwasi/src/uvwasi.c | 55 +++++++++++--- test/wasi/c/create_symlink.c | 2 +- test/wasi/test-wasi-symlinks.js | 20 +++-- test/wasi/wasm/create_symlink.wasm | Bin 32338 -> 33221 bytes 6 files changed, 153 insertions(+), 44 deletions(-) diff --git a/deps/uvwasi/include/uvwasi.h b/deps/uvwasi/include/uvwasi.h index a458cfe17daaa3..752c3ba3958e7c 100644 --- a/deps/uvwasi/include/uvwasi.h +++ b/deps/uvwasi/include/uvwasi.h @@ -11,7 +11,7 @@ extern "C" { #define UVWASI_VERSION_MAJOR 0 #define UVWASI_VERSION_MINOR 0 -#define UVWASI_VERSION_PATCH 19 +#define UVWASI_VERSION_PATCH 20 #define UVWASI_VERSION_HEX ((UVWASI_VERSION_MAJOR << 16) | \ (UVWASI_VERSION_MINOR << 8) | \ (UVWASI_VERSION_PATCH)) diff --git a/deps/uvwasi/src/path_resolver.c b/deps/uvwasi/src/path_resolver.c index af13c1553ca874..ec8946b1393d74 100644 --- a/deps/uvwasi/src/path_resolver.c +++ b/deps/uvwasi/src/path_resolver.c @@ -31,6 +31,42 @@ static char* uvwasi__strchr_slash(const char* s) { return NULL; } +static uvwasi_errno_t uvwasi__combine_paths(const uvwasi_t* uvwasi, + const char* path1, + uvwasi_size_t path1_len, + const char* path2, + uvwasi_size_t path2_len, + char** combined_path, + uvwasi_size_t* combined_len) { + /* This function joins two paths with '/'. */ + uvwasi_errno_t err; + char* combined; + int combined_size; + int r; + + *combined_path = NULL; + *combined_len = 0; + + /* The max combined size is the path1 length + the path2 length + + 2 for a terminating NULL and a possible path separator. */ + combined_size = path1_len + path2_len + 2; + combined = uvwasi__malloc(uvwasi, combined_size); + if (combined == NULL) return UVWASI_ENOMEM; + + r = snprintf(combined, combined_size, "%s/%s", path1, path2); + if (r <= 0) { + err = uvwasi__translate_uv_error(uv_translate_sys_error(errno)); + goto exit; + } + + err = UVWASI_ESUCCESS; + *combined_path = combined; + *combined_len = strlen(combined); + +exit: + if (err != UVWASI_ESUCCESS) uvwasi__free(uvwasi, combined); + return err; +} uvwasi_errno_t uvwasi__normalize_path(const char* path, uvwasi_size_t path_len, @@ -234,39 +270,35 @@ static uvwasi_errno_t uvwasi__normalize_relative_path( uvwasi_errno_t err; char* combined; char* normalized; - int combined_size; - int fd_path_len; - int norm_len; - int r; + uvwasi_size_t combined_len; + uvwasi_size_t fd_path_len; + uvwasi_size_t norm_len; *normalized_path = NULL; *normalized_len = 0; - /* The max combined size is the path length + the file descriptor's path - length + 2 for a terminating NULL and a possible path separator. */ fd_path_len = strlen(fd->normalized_path); - combined_size = path_len + fd_path_len + 2; - combined = uvwasi__malloc(uvwasi, combined_size); - if (combined == NULL) - return UVWASI_ENOMEM; - normalized = uvwasi__malloc(uvwasi, combined_size); + err = uvwasi__combine_paths(uvwasi, + fd->normalized_path, + fd_path_len, + path, + path_len, + &combined, + &combined_len); + if (err != UVWASI_ESUCCESS) goto exit; + + normalized = uvwasi__malloc(uvwasi, combined_len + 1); if (normalized == NULL) { err = UVWASI_ENOMEM; goto exit; } - r = snprintf(combined, combined_size, "%s/%s", fd->normalized_path, path); - if (r <= 0) { - err = uvwasi__translate_uv_error(uv_translate_sys_error(errno)); - goto exit; - } - /* Normalize the input path. */ err = uvwasi__normalize_path(combined, - combined_size - 1, + combined_len, normalized, - combined_size - 1); + combined_len); if (err != UVWASI_ESUCCESS) goto exit; @@ -374,9 +406,14 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi, char* host_path; char* normalized_path; char* link_target; + char* normalized_parent; + char* resolved_link_target; uvwasi_size_t input_len; uvwasi_size_t host_path_len; uvwasi_size_t normalized_len; + uvwasi_size_t link_target_len; + uvwasi_size_t normalized_parent_len; + uvwasi_size_t resolved_link_target_len; int follow_count; int r; @@ -385,6 +422,8 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi, link_target = NULL; follow_count = 0; host_path = NULL; + normalized_parent = NULL; + resolved_link_target = NULL; start: normalized_path = NULL; @@ -458,19 +497,47 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi, goto exit; } - input_len = strlen(req.ptr); + link_target_len = strlen(req.ptr); uvwasi__free(uvwasi, link_target); - link_target = uvwasi__malloc(uvwasi, input_len + 1); + link_target = uvwasi__malloc(uvwasi, link_target_len + 1); if (link_target == NULL) { uv_fs_req_cleanup(&req); err = UVWASI_ENOMEM; goto exit; } - memcpy(link_target, req.ptr, input_len + 1); - input = link_target; - uvwasi__free(uvwasi, normalized_path); + memcpy(link_target, req.ptr, link_target_len + 1); uv_fs_req_cleanup(&req); + + if (1 == uvwasi__is_absolute_path(link_target, link_target_len)) { + input = link_target; + input_len = link_target_len; + } else { + uvwasi__free(uvwasi, normalized_parent); + uvwasi__free(uvwasi, resolved_link_target); + + err = uvwasi__combine_paths(uvwasi, + normalized_path, + normalized_len, + "..", + 2, + &normalized_parent, + &normalized_parent_len); + if (err != UVWASI_ESUCCESS) goto exit; + err = uvwasi__combine_paths(uvwasi, + normalized_parent, + normalized_parent_len, + link_target, + link_target_len, + &resolved_link_target, + &resolved_link_target_len); + if (err != UVWASI_ESUCCESS) goto exit; + + input = resolved_link_target; + input_len = resolved_link_target_len; + } + + uvwasi__free(uvwasi, normalized_path); goto start; } @@ -484,5 +551,8 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi, uvwasi__free(uvwasi, link_target); uvwasi__free(uvwasi, normalized_path); + uvwasi__free(uvwasi, normalized_parent); + uvwasi__free(uvwasi, resolved_link_target); + return err; } diff --git a/deps/uvwasi/src/uvwasi.c b/deps/uvwasi/src/uvwasi.c index e904b9f9293864..40162f886fa224 100644 --- a/deps/uvwasi/src/uvwasi.c +++ b/deps/uvwasi/src/uvwasi.c @@ -8,6 +8,8 @@ # include # include #else +# define _CRT_INTERNAL_NONSTDC_NAMES 1 +# include # include #endif /* _WIN32 */ @@ -17,6 +19,10 @@ # define UVWASI_FD_READDIR_SUPPORTED 1 #endif +#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR) + #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif + #include "uvwasi.h" #include "uvwasi_alloc.h" #include "uv.h" @@ -37,10 +43,13 @@ #define VALIDATE_FSTFLAGS_OR_RETURN(flags) \ do { \ - if ((flags) & ~(UVWASI_FILESTAT_SET_ATIM | \ - UVWASI_FILESTAT_SET_ATIM_NOW | \ - UVWASI_FILESTAT_SET_MTIM | \ - UVWASI_FILESTAT_SET_MTIM_NOW)) { \ + uvwasi_fstflags_t f = flags; \ + if (((f) & ~(UVWASI_FILESTAT_SET_ATIM | UVWASI_FILESTAT_SET_ATIM_NOW | \ + UVWASI_FILESTAT_SET_MTIM | UVWASI_FILESTAT_SET_MTIM_NOW)) || \ + ((f) & (UVWASI_FILESTAT_SET_ATIM | UVWASI_FILESTAT_SET_ATIM_NOW)) \ + == (UVWASI_FILESTAT_SET_ATIM | UVWASI_FILESTAT_SET_ATIM_NOW) || \ + ((f) & (UVWASI_FILESTAT_SET_MTIM | UVWASI_FILESTAT_SET_MTIM_NOW)) \ + == (UVWASI_FILESTAT_SET_MTIM | UVWASI_FILESTAT_SET_MTIM_NOW)) { \ return UVWASI_EINVAL; \ } \ } while (0) @@ -624,9 +633,10 @@ uvwasi_errno_t uvwasi_fd_advise(uvwasi_t* uvwasi, uvwasi_advice_t advice) { struct uvwasi_fd_wrap_t* wrap; uvwasi_errno_t err; + uv_fs_t req; + int r; #ifdef POSIX_FADV_NORMAL int mapped_advice; - int r; #endif /* POSIX_FADV_NORMAL */ UVWASI_DEBUG("uvwasi_fd_advise(uvwasi=%p, fd=%d, offset=%"PRIu64", " @@ -679,6 +689,17 @@ uvwasi_errno_t uvwasi_fd_advise(uvwasi_t* uvwasi, if (err != UVWASI_ESUCCESS) return err; + r = uv_fs_fstat(NULL, &req, wrap->fd, NULL); + if (r == -1) { + err = uvwasi__translate_uv_error(r); + goto exit; + } + + if (S_ISDIR(req.statbuf.st_mode)) { + err = UVWASI_EBADF; + goto exit; + } + err = UVWASI_ESUCCESS; #ifdef POSIX_FADV_NORMAL @@ -686,7 +707,9 @@ uvwasi_errno_t uvwasi_fd_advise(uvwasi_t* uvwasi, if (r != 0) err = uvwasi__translate_uv_error(uv_translate_sys_error(r)); #endif /* POSIX_FADV_NORMAL */ +exit: uv_mutex_unlock(&wrap->mutex); + uv_fs_req_cleanup(&req); return err; } @@ -1775,8 +1798,6 @@ uvwasi_errno_t uvwasi_path_filestat_set_times(uvwasi_t* uvwasi, if (uvwasi == NULL || path == NULL) return UVWASI_EINVAL; - VALIDATE_FSTFLAGS_OR_RETURN(fst_flags); - err = uvwasi_fd_table_get(uvwasi->fds, fd, &wrap, @@ -1785,6 +1806,8 @@ uvwasi_errno_t uvwasi_path_filestat_set_times(uvwasi_t* uvwasi, if (err != UVWASI_ESUCCESS) return err; + VALIDATE_FSTFLAGS_OR_RETURN(fst_flags); + err = uvwasi__resolve_path(uvwasi, wrap, path, @@ -2306,6 +2329,7 @@ uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi, uvwasi_fd_t fd, const char* new_path, uvwasi_size_t new_path_len) { + char* truncated_old_path; char* resolved_new_path; struct uvwasi_fd_wrap_t* wrap; uvwasi_errno_t err; @@ -2332,6 +2356,15 @@ uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi, if (err != UVWASI_ESUCCESS) return err; + truncated_old_path = uvwasi__malloc(uvwasi, old_path_len + 1); + if (truncated_old_path == NULL) { + uv_mutex_unlock(&wrap->mutex); + return UVWASI_ENOMEM; + } + + memcpy(truncated_old_path, old_path, old_path_len); + truncated_old_path[old_path_len] = '\0'; + err = uvwasi__resolve_path(uvwasi, wrap, new_path, @@ -2340,12 +2373,14 @@ uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi, 0); if (err != UVWASI_ESUCCESS) { uv_mutex_unlock(&wrap->mutex); + uvwasi__free(uvwasi, truncated_old_path); return err; } /* Windows support may require setting the flags option. */ - r = uv_fs_symlink(NULL, &req, old_path, resolved_new_path, 0, NULL); + r = uv_fs_symlink(NULL, &req, truncated_old_path, resolved_new_path, 0, NULL); uv_mutex_unlock(&wrap->mutex); + uvwasi__free(uvwasi, truncated_old_path); uvwasi__free(uvwasi, resolved_new_path); uv_fs_req_cleanup(&req); if (r != 0) @@ -2696,7 +2731,7 @@ uvwasi_errno_t uvwasi_sock_shutdown(uvwasi_t* uvwasi, uvwasi_sdflags_t how) { struct uvwasi_fd_wrap_t* wrap; uvwasi_errno_t err = 0; - shutdown_data_t shutdown_data; + shutdown_data_t shutdown_data = {0}; if (how & ~UVWASI_SHUT_WR) return UVWASI_ENOTSUP; @@ -2794,7 +2829,7 @@ uvwasi_errno_t uvwasi_sock_accept(uvwasi_t* uvwasi, goto close_sock_and_error_exit; } - int r = uv_accept((uv_stream_t*) wrap->sock, (uv_stream_t*) uv_connect_sock); + r = uv_accept((uv_stream_t*) wrap->sock, (uv_stream_t*) uv_connect_sock); if (r == UV_EAGAIN) { // still no connection or error so run the loop again continue; diff --git a/test/wasi/c/create_symlink.c b/test/wasi/c/create_symlink.c index 094484ee7db745..319b10c6909781 100644 --- a/test/wasi/c/create_symlink.c +++ b/test/wasi/c/create_symlink.c @@ -4,7 +4,7 @@ #include int main() { - const char* target = "./input.txt"; + const char* target = "./input-in-subdir.txt"; const char* linkpath = "/sandbox/subdir/test_link"; char readlink_result[128]; size_t result_size = sizeof(readlink_result); diff --git a/test/wasi/test-wasi-symlinks.js b/test/wasi/test-wasi-symlinks.js index 9c95a0e55757d0..fb9fed65c2b480 100644 --- a/test/wasi/test-wasi-symlinks.js +++ b/test/wasi/test-wasi-symlinks.js @@ -42,6 +42,7 @@ if (process.argv[2] === 'wasi-child') { const sandboxedFile = path.join(sandbox, 'input.txt'); const externalFile = tmpdir.resolve('outside.txt'); const sandboxedDir = path.join(sandbox, 'subdir'); + const sandboxedFileInSubdir = path.join(sandboxedDir, 'input-in-subdir.txt'); const sandboxedSymlink = path.join(sandboxedDir, 'input_link.txt'); const escapingSymlink = path.join(sandboxedDir, 'outside.txt'); const loopSymlink1 = path.join(sandboxedDir, 'loop1'); @@ -52,13 +53,14 @@ if (process.argv[2] === 'wasi-child') { fs.mkdirSync(sandboxedDir); fs.mkdirSync(sandboxedTmp); fs.writeFileSync(sandboxedFile, 'hello from input.txt', 'utf8'); + fs.writeFileSync(sandboxedFileInSubdir, 'hello from input in subdir.txt', + 'utf8'); fs.writeFileSync(externalFile, 'this should be inaccessible', 'utf8'); - fs.symlinkSync(path.join('.', 'input.txt'), sandboxedSymlink, 'file'); - fs.symlinkSync(path.join('..', 'outside.txt'), escapingSymlink, 'file'); - fs.symlinkSync(path.join('subdir', 'loop2'), - loopSymlink1, 'file'); - fs.symlinkSync(path.join('subdir', 'loop1'), - loopSymlink2, 'file'); + fs.symlinkSync(path.join('.', 'input-in-subdir.txt'), + sandboxedSymlink, 'file'); + fs.symlinkSync(path.join('..', '..', 'outside.txt'), escapingSymlink, 'file'); + fs.symlinkSync('loop2', loopSymlink1, 'file'); + fs.symlinkSync('loop1', loopSymlink2, 'file'); function runWASI(options) { console.log('executing', options.test); @@ -76,8 +78,10 @@ if (process.argv[2] === 'wasi-child') { assert.strictEqual(child.stdout.toString(), options.stdout || ''); } - runWASI({ test: 'create_symlink', stdout: 'hello from input.txt' }); - runWASI({ test: 'follow_symlink', stdout: 'hello from input.txt' }); + runWASI({ test: 'create_symlink', + stdout: 'hello from input in subdir.txt' }); + runWASI({ test: 'follow_symlink', + stdout: 'hello from input in subdir.txt' }); runWASI({ test: 'link' }); runWASI({ test: 'symlink_escape' }); runWASI({ test: 'symlink_loop' }); diff --git a/test/wasi/wasm/create_symlink.wasm b/test/wasi/wasm/create_symlink.wasm index 89a24c50ca314661d55d2c3ed105f6c09b36cf7b..64e120cd5a617bfe25d5d8d2f4221f2859ad8ef5 100755 GIT binary patch literal 33221 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