From c7a1fd4e0c236c1ffaaa6490c852a9895e6e74dc Mon Sep 17 00:00:00 2001 From: Yage Hu Date: Wed, 12 Jun 2024 11:16:54 -0700 Subject: [PATCH] Error if creating symlink to absolute path This commit adds an absolute path check to `path_symlink`. This behavior is specified by [WASI][1]. [1]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md#symlinks fixes #271 Signed-off-by: Yage Hu --- src/uvwasi.c | 5 +++ test/test-path-symlink-absolute-path.c | 48 ++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 test/test-path-symlink-absolute-path.c diff --git a/src/uvwasi.c b/src/uvwasi.c index 2c46046..ff03bd8 100644 --- a/src/uvwasi.c +++ b/src/uvwasi.c @@ -2401,6 +2401,11 @@ uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi, memcpy(truncated_old_path, old_path, old_path_len); truncated_old_path[old_path_len] = '\0'; + if (old_path_len > 0 && old_path[0] == '/') { + uv_mutex_unlock(&wrap->mutex); + return UVWASI_EPERM; + } + err = uvwasi__resolve_path(uvwasi, wrap, new_path, diff --git a/test/test-path-symlink-absolute-path.c b/test/test-path-symlink-absolute-path.c new file mode 100644 index 0000000..844bcfa --- /dev/null +++ b/test/test-path-symlink-absolute-path.c @@ -0,0 +1,48 @@ +#include +#include +#include +#include +#include "uvwasi.h" +#include "uv.h" +#include "test-common.h" + +#define TEST_TMP_DIR "./out/tmp" +#define LINK_CONTENT "/absolute" +#define TEST_FILE "./out/tmp/test-path-symlink-absolute-path.link" + +int main(void) { + uvwasi_t uvwasi; + uvwasi_fd_t fd; + uvwasi_options_t init_options; + uvwasi_errno_t err; + uv_fs_t req; + int r; + + setup_test_environment(); + + r = uv_fs_mkdir(NULL, &req, TEST_TMP_DIR, 0777, NULL); + uv_fs_req_cleanup(&req); + assert(r == 0 || r == UV_EEXIST); + + uvwasi_options_init(&init_options); + init_options.preopenc = 1; + init_options.preopens = calloc(1, sizeof(uvwasi_preopen_t)); + init_options.preopens[0].mapped_path = "/var"; + init_options.preopens[0].real_path = TEST_TMP_DIR; + + err = uvwasi_init(&uvwasi, &init_options); + assert(err == 0); + + err = uvwasi_path_symlink(&uvwasi, + LINK_CONTENT, + strlen(LINK_CONTENT) + 1, + 3, + TEST_FILE, + strlen(TEST_FILE) + 1); + assert(err == UVWASI_EPERM); + + uvwasi_destroy(&uvwasi); + free(init_options.preopens); + + return 0; +}