diff --git a/src/path_resolver.c b/src/path_resolver.c index afafac0..77f0623 100644 --- a/src/path_resolver.c +++ b/src/path_resolver.c @@ -440,6 +440,11 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi, normalized_parent = NULL; resolved_link_target = NULL; + if (uvwasi__is_absolute_path(input, input_len)) { + *resolved_path = NULL; + return UVWASI_ENOTCAPABLE; + } + start: normalized_path = NULL; err = UVWASI_ESUCCESS; diff --git a/test/test-path-open-absolute.c b/test/test-path-open-absolute.c new file mode 100644 index 0000000..a647035 --- /dev/null +++ b/test/test-path-open-absolute.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include "uvwasi.h" +#include "uv.h" +#include "test-common.h" + +#define TEST_TMP_DIR "./out/tmp" +#define TEST_FILE "/test-path-open-absolute.file" +#define OFLAGS_CREAT 1 +#define RIGHTS_FD_WRITE 64 + +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_open(&uvwasi, + 3, + 0, + TEST_FILE, + strlen(TEST_FILE) + 1, + OFLAGS_CREAT, + RIGHTS_FD_WRITE, + 0, + 0, + &fd); + assert(err == UVWASI_ENOTCAPABLE && "open absolute path should fail"); + + uvwasi_destroy(&uvwasi); + free(init_options.preopens); + + return 0; +} diff --git a/test/test-path-resolution.c b/test/test-path-resolution.c index 40b7415..4c03e2e 100644 --- a/test/test-path-resolution.c +++ b/test/test-path-resolution.c @@ -182,13 +182,13 @@ int main(void) { /* Arguments: fd mapped path, fd real path, path to resolve, expected path */ pass("/", "/foo", "test_path", "/foo/test_path"); - pass("/", "/foo", "/test_path", "/foo/test_path"); + pass("/", "/foo", "test_path", "/foo/test_path"); pass("/bar", "/baz", "test_path", "/baz/test_path"); pass("/bar", "/baz", "./test_path", "/baz/test_path"); pass("/bar", "/baz", "../bar/test_path", "/baz/test_path"); pass("/bar", "/baz", "../bar/./test_path/../test_path", "/baz/test_path"); - pass("/bar", "/baz", "/bar/test_path", "/baz/test_path"); - pass("/bar", "/baz", "/bar/../bar/test_path", "/baz/test_path"); + pass("/bar", "/baz", "bar/test_path", "/baz/bar/test_path"); + pass("/bar", "/baz", "bar/../bar/test_path", "/baz/bar/test_path"); pass(".", "/foo", "test_path", "/foo/test_path"); pass("./", "/foo", "test_path", "/foo/test_path"); pass(".", "/foo", "./test_path", "/foo/test_path"); @@ -222,16 +222,16 @@ int main(void) { create_symlink("./qux", TEST_TMP_DIR "/dir/quux"); /* Arguments: fd mapped path, fd real path, path to resolve, expected path */ - pass_follow("/", TEST_TMP_DIR, "/bar", TEST_TMP_DIR "/foo"); - pass_follow("/", TEST_TMP_DIR, "/bar2", TEST_TMP_DIR "/foo"); - pass_follow("/", TEST_TMP_DIR, "/bar3", TEST_TMP_DIR "/foo"); - pass_follow("/", TEST_TMP_DIR, "/bar4", TEST_TMP_DIR "/foo"); - pass_follow("/", TEST_TMP_DIR, "/bar5", TEST_TMP_DIR "/foo"); - pass_follow("/", TEST_TMP_DIR, "/baz", TEST_TMP_DIR "/foo"); - pass_follow("/", TEST_TMP_DIR, "/baz2", TEST_TMP_DIR "/foo"); - pass_follow("/", TEST_TMP_DIR, "/baz3", TEST_TMP_DIR "/foo"); - pass_follow("/", TEST_TMP_DIR, "/dir/qux", TEST_TMP_DIR "/foo"); - pass_follow("/", TEST_TMP_DIR, "/dir/quux", TEST_TMP_DIR "/foo"); + pass_follow("/", TEST_TMP_DIR, "bar", TEST_TMP_DIR "/foo"); + pass_follow("/", TEST_TMP_DIR, "bar2", TEST_TMP_DIR "/foo"); + pass_follow("/", TEST_TMP_DIR, "bar3", TEST_TMP_DIR "/foo"); + pass_follow("/", TEST_TMP_DIR, "bar4", TEST_TMP_DIR "/foo"); + pass_follow("/", TEST_TMP_DIR, "bar5", TEST_TMP_DIR "/foo"); + pass_follow("/", TEST_TMP_DIR, "baz", TEST_TMP_DIR "/foo"); + pass_follow("/", TEST_TMP_DIR, "baz2", TEST_TMP_DIR "/foo"); + pass_follow("/", TEST_TMP_DIR, "baz3", TEST_TMP_DIR "/foo"); + pass_follow("/", TEST_TMP_DIR, "dir/qux", TEST_TMP_DIR "/foo"); + pass_follow("/", TEST_TMP_DIR, "dir/quux", TEST_TMP_DIR "/foo"); /* Arguments: fd mapped path, fd real path, path to resolve, expected error */ fail_follow("/dir", TEST_TMP_DIR "/dir", "/dir/qux", UVWASI_ENOTCAPABLE);