Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 7 additions & 12 deletions src/path_resolver.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
const struct uvwasi_fd_wrap_t* fd,
const char* path,
size_t path_len,
char* resolved_path,
char** resolved_path,
uvwasi_lookupflags_t flags) {
uv_fs_t req;
uvwasi_errno_t err;
Expand Down Expand Up @@ -418,14 +418,6 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
goto exit;

/* TODO(cjihrig): Currently performing a bounds check here. The TODO is to
stop allocating resolved_path in every caller and instead return the
path allocated in this function. */
if (host_path_len > PATH_MAX_BYTES) {
err = UVWASI_ENOBUFS;
goto exit;
}

if ((flags & UVWASI_LOOKUP_SYMLINK_FOLLOW) == UVWASI_LOOKUP_SYMLINK_FOLLOW) {
r = uv_fs_readlink(NULL, &req, host_path, NULL);

Expand Down Expand Up @@ -482,11 +474,14 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
}

exit:
if (err == UVWASI_ESUCCESS)
memcpy(resolved_path, host_path, host_path_len + 1);
if (err == UVWASI_ESUCCESS) {
*resolved_path = host_path;
} else {
*resolved_path = NULL;
uvwasi__free(uvwasi, host_path);
}

uvwasi__free(uvwasi, link_target);
uvwasi__free(uvwasi, normalized_path);
uvwasi__free(uvwasi, host_path);
return err;
}
12 changes: 1 addition & 11 deletions src/path_resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,6 @@

#include "uvwasi.h"

/* TODO(cjihrig): PATH_MAX_BYTES shouldn't be stack allocated. On Windows, paths
can be 32k long, and this PATH_MAX_BYTES is an artificial limitation. */
#ifdef _WIN32
/* MAX_PATH is in characters, not bytes. Make sure we have enough headroom. */
# define PATH_MAX_BYTES (MAX_PATH * 4)
#else
# include <limits.h>
# define PATH_MAX_BYTES (PATH_MAX)
#endif

uvwasi_errno_t uvwasi__normalize_path(const char* path,
size_t path_len,
char* normalized_path,
Expand All @@ -22,7 +12,7 @@ uvwasi_errno_t uvwasi__resolve_path(const uvwasi_t* uvwasi,
const struct uvwasi_fd_wrap_t* fd,
const char* path,
size_t path_len,
char* resolved_path,
char** resolved_path,
uvwasi_lookupflags_t flags);

#endif /* __UVWASI_PATH_RESOLVER_H__ */
72 changes: 47 additions & 25 deletions src/uvwasi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1443,7 +1443,7 @@ uvwasi_errno_t uvwasi_path_create_directory(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
size_t path_len) {
char resolved_path[PATH_MAX_BYTES];
char* resolved_path;
struct uvwasi_fd_wrap_t* wrap;
uv_fs_t req;
uvwasi_errno_t err;
Expand All @@ -1467,12 +1467,13 @@ uvwasi_errno_t uvwasi_path_create_directory(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;

err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, &resolved_path, 0);
if (err != UVWASI_ESUCCESS)
goto exit;

r = uv_fs_mkdir(NULL, &req, resolved_path, 0777, NULL);
uv_fs_req_cleanup(&req);
uvwasi__free(uvwasi, resolved_path);

if (r != 0) {
err = uvwasi__translate_uv_error(r);
Expand All @@ -1492,7 +1493,7 @@ uvwasi_errno_t uvwasi_path_filestat_get(uvwasi_t* uvwasi,
const char* path,
size_t path_len,
uvwasi_filestat_t* buf) {
char resolved_path[PATH_MAX_BYTES];
char* resolved_path;
struct uvwasi_fd_wrap_t* wrap;
uv_fs_t req;
uvwasi_errno_t err;
Expand Down Expand Up @@ -1522,12 +1523,13 @@ uvwasi_errno_t uvwasi_path_filestat_get(uvwasi_t* uvwasi,
wrap,
path,
path_len,
resolved_path,
&resolved_path,
flags);
if (err != UVWASI_ESUCCESS)
goto exit;

r = uv_fs_stat(NULL, &req, resolved_path, NULL);
uvwasi__free(uvwasi, resolved_path);
if (r != 0) {
uv_fs_req_cleanup(&req);
err = uvwasi__translate_uv_error(r);
Expand All @@ -1552,7 +1554,7 @@ uvwasi_errno_t uvwasi_path_filestat_set_times(uvwasi_t* uvwasi,
uvwasi_timestamp_t st_mtim,
uvwasi_fstflags_t fst_flags) {
/* TODO(cjihrig): libuv does not currently support nanosecond precision. */
char resolved_path[PATH_MAX_BYTES];
char* resolved_path;
struct uvwasi_fd_wrap_t* wrap;
uv_fs_t req;
uvwasi_errno_t err;
Expand Down Expand Up @@ -1589,13 +1591,14 @@ uvwasi_errno_t uvwasi_path_filestat_set_times(uvwasi_t* uvwasi,
wrap,
path,
path_len,
resolved_path,
&resolved_path,
flags);
if (err != UVWASI_ESUCCESS)
goto exit;

/* TODO(cjihrig): st_atim and st_mtim should not be unconditionally passed. */
r = uv_fs_utime(NULL, &req, resolved_path, st_atim, st_mtim, NULL);
uvwasi__free(uvwasi, resolved_path);
uv_fs_req_cleanup(&req);

if (r != 0) {
Expand All @@ -1618,8 +1621,8 @@ uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
uvwasi_fd_t new_fd,
const char* new_path,
size_t new_path_len) {
char resolved_old_path[PATH_MAX_BYTES];
char resolved_new_path[PATH_MAX_BYTES];
char* resolved_old_path;
char* resolved_new_path;
struct uvwasi_fd_wrap_t* old_wrap;
struct uvwasi_fd_wrap_t* new_wrap;
uvwasi_errno_t err;
Expand Down Expand Up @@ -1675,11 +1678,14 @@ uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;

resolved_old_path = NULL;
resolved_new_path = NULL;

err = uvwasi__resolve_path(uvwasi,
old_wrap,
old_path,
old_path_len,
resolved_old_path,
&resolved_old_path,
old_flags);
if (err != UVWASI_ESUCCESS)
goto exit;
Expand All @@ -1688,7 +1694,7 @@ uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
new_wrap,
new_path,
new_path_len,
resolved_new_path,
&resolved_new_path,
0);
if (err != UVWASI_ESUCCESS)
goto exit;
Expand All @@ -1705,6 +1711,9 @@ uvwasi_errno_t uvwasi_path_link(uvwasi_t* uvwasi,
uv_mutex_unlock(&new_wrap->mutex);
if (old_fd != new_fd)
uv_mutex_unlock(&old_wrap->mutex);

uvwasi__free(uvwasi, resolved_old_path);
uvwasi__free(uvwasi, resolved_new_path);
return err;
}

Expand All @@ -1719,7 +1728,7 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
uvwasi_rights_t fs_rights_inheriting,
uvwasi_fdflags_t fs_flags,
uvwasi_fd_t* fd) {
char resolved_path[PATH_MAX_BYTES];
char* resolved_path;
uvwasi_rights_t needed_inheriting;
uvwasi_rights_t needed_base;
uvwasi_rights_t max_base;
Expand Down Expand Up @@ -1809,7 +1818,7 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
dirfd_wrap,
path,
path_len,
resolved_path,
&resolved_path,
dirflags);
if (err != UVWASI_ESUCCESS) {
uv_mutex_unlock(&dirfd_wrap->mutex);
Expand All @@ -1820,8 +1829,10 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
uv_mutex_unlock(&dirfd_wrap->mutex);
uv_fs_req_cleanup(&req);

if (r < 0)
if (r < 0) {
uvwasi__free(uvwasi, resolved_path);
return uvwasi__translate_uv_error(r);
}

/* Not all platforms support UV_FS_O_DIRECTORY, so get the file type and check
it here. */
Expand Down Expand Up @@ -1854,11 +1865,13 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,

*fd = wrap->id;
uv_mutex_unlock(&wrap->mutex);
uvwasi__free(uvwasi, resolved_path);
return UVWASI_ESUCCESS;

close_file_and_error_exit:
uv_fs_close(NULL, &req, r, NULL);
uv_fs_req_cleanup(&req);
uvwasi__free(uvwasi, resolved_path);
return err;
}

Expand All @@ -1870,7 +1883,7 @@ uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
char* buf,
size_t buf_len,
size_t* bufused) {
char resolved_path[PATH_MAX_BYTES];
char* resolved_path;
struct uvwasi_fd_wrap_t* wrap;
uvwasi_errno_t err;
uv_fs_t req;
Expand Down Expand Up @@ -1898,14 +1911,15 @@ uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;

err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, &resolved_path, 0);
if (err != UVWASI_ESUCCESS) {
uv_mutex_unlock(&wrap->mutex);
return err;
}

r = uv_fs_readlink(NULL, &req, resolved_path, NULL);
uv_mutex_unlock(&wrap->mutex);
uvwasi__free(uvwasi, resolved_path);
if (r != 0) {
uv_fs_req_cleanup(&req);
return uvwasi__translate_uv_error(r);
Expand All @@ -1929,7 +1943,7 @@ uvwasi_errno_t uvwasi_path_remove_directory(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
size_t path_len) {
char resolved_path[PATH_MAX_BYTES];
char* resolved_path;
struct uvwasi_fd_wrap_t* wrap;
uv_fs_t req;
uvwasi_errno_t err;
Expand All @@ -1953,14 +1967,15 @@ uvwasi_errno_t uvwasi_path_remove_directory(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;

err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, &resolved_path, 0);
if (err != UVWASI_ESUCCESS) {
uv_mutex_unlock(&wrap->mutex);
return err;
}

r = uv_fs_rmdir(NULL, &req, resolved_path, NULL);
uv_mutex_unlock(&wrap->mutex);
uvwasi__free(uvwasi, resolved_path);
uv_fs_req_cleanup(&req);

if (r != 0)
Expand All @@ -1977,8 +1992,8 @@ uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
uvwasi_fd_t new_fd,
const char* new_path,
size_t new_path_len) {
char resolved_old_path[PATH_MAX_BYTES];
char resolved_new_path[PATH_MAX_BYTES];
char* resolved_old_path;
char* resolved_new_path;
struct uvwasi_fd_wrap_t* old_wrap;
struct uvwasi_fd_wrap_t* new_wrap;
uvwasi_errno_t err;
Expand Down Expand Up @@ -2033,11 +2048,14 @@ uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;

resolved_old_path = NULL;
resolved_new_path = NULL;

err = uvwasi__resolve_path(uvwasi,
old_wrap,
old_path,
old_path_len,
resolved_old_path,
&resolved_old_path,
0);
if (err != UVWASI_ESUCCESS)
goto exit;
Expand All @@ -2046,7 +2064,7 @@ uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
new_wrap,
new_path,
new_path_len,
resolved_new_path,
&resolved_new_path,
0);
if (err != UVWASI_ESUCCESS)
goto exit;
Expand All @@ -2064,6 +2082,8 @@ uvwasi_errno_t uvwasi_path_rename(uvwasi_t* uvwasi,
if (old_fd != new_fd)
uv_mutex_unlock(&old_wrap->mutex);

uvwasi__free(uvwasi, resolved_old_path);
uvwasi__free(uvwasi, resolved_new_path);
return err;
}

Expand All @@ -2074,7 +2094,7 @@ uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* new_path,
size_t new_path_len) {
char resolved_new_path[PATH_MAX_BYTES];
char* resolved_new_path;
struct uvwasi_fd_wrap_t* wrap;
uvwasi_errno_t err;
uv_fs_t req;
Expand Down Expand Up @@ -2104,7 +2124,7 @@ uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
wrap,
new_path,
new_path_len,
resolved_new_path,
&resolved_new_path,
0);
if (err != UVWASI_ESUCCESS) {
uv_mutex_unlock(&wrap->mutex);
Expand All @@ -2114,6 +2134,7 @@ uvwasi_errno_t uvwasi_path_symlink(uvwasi_t* uvwasi,
/* Windows support may require setting the flags option. */
r = uv_fs_symlink(NULL, &req, old_path, resolved_new_path, 0, NULL);
uv_mutex_unlock(&wrap->mutex);
uvwasi__free(uvwasi, resolved_new_path);
uv_fs_req_cleanup(&req);
if (r != 0)
return uvwasi__translate_uv_error(r);
Expand All @@ -2126,7 +2147,7 @@ uvwasi_errno_t uvwasi_path_unlink_file(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
size_t path_len) {
char resolved_path[PATH_MAX_BYTES];
char* resolved_path;
struct uvwasi_fd_wrap_t* wrap;
uv_fs_t req;
uvwasi_errno_t err;
Expand All @@ -2149,14 +2170,15 @@ uvwasi_errno_t uvwasi_path_unlink_file(uvwasi_t* uvwasi,
if (err != UVWASI_ESUCCESS)
return err;

err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, resolved_path, 0);
err = uvwasi__resolve_path(uvwasi, wrap, path, path_len, &resolved_path, 0);
if (err != UVWASI_ESUCCESS) {
uv_mutex_unlock(&wrap->mutex);
return err;
}

r = uv_fs_unlink(NULL, &req, resolved_path, NULL);
uv_mutex_unlock(&wrap->mutex);
uvwasi__free(uvwasi, resolved_path);
uv_fs_req_cleanup(&req);

if (r != 0)
Expand Down
Loading