Skip to content

Commit

Permalink
Disallow absolute path at the raw WASI level (#270)
Browse files Browse the repository at this point in the history
This commit fixes a `path_open` behavior that allows opening absolute
paths. Although the path normalization correctly resolves the path and
enforces the sandbox, it's still a good idea to converge with other
runtimes here.

fixes #269

Signed-off-by: Yage Hu <me@huyage.dev>
  • Loading branch information
yagehu authored Jun 14, 2024
1 parent afffaaa commit 9811374
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 13 deletions.
5 changes: 5 additions & 0 deletions src/path_resolver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
53 changes: 53 additions & 0 deletions test/test-path-open-absolute.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#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;
}
26 changes: 13 additions & 13 deletions test/test-path-resolution.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 9811374

Please sign in to comment.