Skip to content

Commit

Permalink
Ignore rights in libpreopen. (WebAssembly#129)
Browse files Browse the repository at this point in the history
Don't ignore paths which don't have the required rights. This means
that if the lookup finds a path that doesn't have the required
rights, it'll just proceed to the actual operation which will fail
with `ENOTCAPABLE`.

Intuitively, use cases which would depend on having multiple
overlapping matching paths for a given lookup and intelligently
picking the one with the required rights seems like they should
be uncommon.

This is simpler overall, and requires less code.
  • Loading branch information
sunfishcode committed Nov 21, 2019
1 parent 8c9e1c6 commit 54102f0
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 67 deletions.
8 changes: 2 additions & 6 deletions libc-bottom-half/headers/public/wasi/libc-find-relpath.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,11 @@ extern "C" {
/**
* Look up the given path in the preopened directory map. If a suitable
* entry is found, return its directory file descriptor, and store the
* computed relative path in *relative_path. Ignore preopened directories
* which don't provide the specified rights.
* computed relative path in *relative_path.
*
* Returns -1 if no directories were suitable.
*/
int __wasilibc_find_relpath(const char *path,
__wasi_rights_t rights_base,
__wasi_rights_t rights_inheriting,
const char **relative_path);
int __wasilibc_find_relpath(const char *path, const char **relative_path);

#ifdef __cplusplus
}
Expand Down
79 changes: 18 additions & 61 deletions libc-bottom-half/libpreopen/libpreopen.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ int
__wasilibc_open_nomode(const char *path, int flags)
{
const char *relative_path;
int dirfd = __wasilibc_find_relpath(path, __WASI_RIGHT_PATH_OPEN, 0,
&relative_path);
int dirfd = __wasilibc_find_relpath(path, &relative_path);

// If we can't find a preopened directory handle to open this file with,
// indicate that the program lacks the capabilities.
Expand All @@ -92,8 +91,7 @@ int
access(const char *path, int mode)
{
const char *relative_path;
int dirfd = __wasilibc_find_relpath(path, __WASI_RIGHT_PATH_FILESTAT_GET, 0,
&relative_path);
int dirfd = __wasilibc_find_relpath(path, &relative_path);

// If we can't find a preopened directory handle to open this file with,
// indicate that the program lacks the capabilities.
Expand All @@ -109,8 +107,7 @@ int
lstat(const char *path, struct stat *st)
{
const char *relative_path;
int dirfd = __wasilibc_find_relpath(path, __WASI_RIGHT_PATH_FILESTAT_GET, 0,
&relative_path);
int dirfd = __wasilibc_find_relpath(path, &relative_path);

// If we can't find a preopened directory handle to open this file with,
// indicate that the program lacks the capabilities.
Expand All @@ -126,12 +123,10 @@ int
rename(const char *from, const char *to)
{
const char *from_relative_path;
int from_dirfd = __wasilibc_find_relpath(from, __WASI_RIGHT_PATH_RENAME_SOURCE, 0,
&from_relative_path);
int from_dirfd = __wasilibc_find_relpath(from, &from_relative_path);

const char *to_relative_path;
int to_dirfd = __wasilibc_find_relpath(to, __WASI_RIGHT_PATH_RENAME_TARGET, 0,
&to_relative_path);
int to_dirfd = __wasilibc_find_relpath(to, &to_relative_path);

// If we can't find a preopened directory handle to open this file with,
// indicate that the program lacks the capabilities.
Expand All @@ -147,8 +142,7 @@ int
stat(const char *path, struct stat *st)
{
const char *relative_path;
int dirfd = __wasilibc_find_relpath(path, __WASI_RIGHT_PATH_FILESTAT_GET, 0,
&relative_path);
int dirfd = __wasilibc_find_relpath(path, &relative_path);

// If we can't find a preopened directory handle to open this file with,
// indicate that the program lacks the capabilities.
Expand All @@ -164,8 +158,7 @@ int
unlink(const char *path)
{
const char *relative_path;
int dirfd = __wasilibc_find_relpath(path, __WASI_RIGHT_PATH_UNLINK_FILE, 0,
&relative_path);
int dirfd = __wasilibc_find_relpath(path, &relative_path);

// If we can't find a preopened directory handle to open this file with,
// indicate that the program lacks the capabilities.
Expand All @@ -184,8 +177,7 @@ int
rmdir(const char *pathname)
{
const char *relative_path;
int dirfd = __wasilibc_find_relpath(pathname, __WASI_RIGHT_PATH_REMOVE_DIRECTORY, 0,
&relative_path);
int dirfd = __wasilibc_find_relpath(pathname, &relative_path);

// If we can't find a preopened directory handle to open this file with,
// indicate that the program lacks the capabilities.
Expand All @@ -201,20 +193,14 @@ int
remove(const char *pathname)
{
const char *relative_path;
int dirfd = __wasilibc_find_relpath(pathname,
__WASI_RIGHT_PATH_UNLINK_FILE |
__WASI_RIGHT_PATH_REMOVE_DIRECTORY,
0,
&relative_path);
int dirfd = __wasilibc_find_relpath(pathname, &relative_path);

// If searching for both file and directory rights failed, try searching
// for either individually.
if (dirfd == -1) {
dirfd = __wasilibc_find_relpath(pathname, __WASI_RIGHT_PATH_UNLINK_FILE, 0,
&relative_path);
dirfd = __wasilibc_find_relpath(pathname, &relative_path);
if (dirfd == -1) {
dirfd = __wasilibc_find_relpath(pathname, __WASI_RIGHT_PATH_REMOVE_DIRECTORY, 0,
&relative_path);
dirfd = __wasilibc_find_relpath(pathname, &relative_path);
}
}

Expand All @@ -235,12 +221,10 @@ int
link(const char *oldpath, const char *newpath)
{
const char *old_relative_path;
int old_dirfd = __wasilibc_find_relpath(oldpath, __WASI_RIGHT_PATH_LINK_SOURCE, 0,
&old_relative_path);
int old_dirfd = __wasilibc_find_relpath(oldpath, &old_relative_path);

const char *new_relative_path;
int new_dirfd = __wasilibc_find_relpath(newpath, __WASI_RIGHT_PATH_LINK_TARGET, 0,
&new_relative_path);
int new_dirfd = __wasilibc_find_relpath(newpath, &new_relative_path);

// If we can't find a preopened directory handle to open this file with,
// indicate that the program lacks the capabilities.
Expand All @@ -256,8 +240,7 @@ int
mkdir(const char *pathname, mode_t mode)
{
const char *relative_path;
int dirfd = __wasilibc_find_relpath(pathname, __WASI_RIGHT_PATH_CREATE_DIRECTORY, 0,
&relative_path);
int dirfd = __wasilibc_find_relpath(pathname, &relative_path);

// If we can't find a preopened directory handle to open this file with,
// indicate that the program lacks the capabilities.
Expand All @@ -273,8 +256,7 @@ DIR *
opendir(const char *name)
{
const char *relative_path;
int dirfd = __wasilibc_find_relpath(name, __WASI_RIGHT_PATH_OPEN, 0,
&relative_path);
int dirfd = __wasilibc_find_relpath(name, &relative_path);

// If we can't find a preopened directory handle to open this file with,
// indicate that the program lacks the capabilities.
Expand All @@ -290,8 +272,7 @@ ssize_t
readlink(const char *pathname, char *buf, size_t bufsiz)
{
const char *relative_path;
int dirfd = __wasilibc_find_relpath(pathname, __WASI_RIGHT_PATH_READLINK, 0,
&relative_path);
int dirfd = __wasilibc_find_relpath(pathname, &relative_path);

// If we can't find a preopened directory handle to open this file with,
// indicate that the program lacks the capabilities.
Expand All @@ -311,10 +292,7 @@ scandir(
int (*compar)(const struct dirent **, const struct dirent **))
{
const char *relative_path;
int dirfd = __wasilibc_find_relpath(dirp,
__WASI_RIGHT_PATH_OPEN,
__WASI_RIGHT_FD_READDIR,
&relative_path);
int dirfd = __wasilibc_find_relpath(dirp, &relative_path);

// If we can't find a preopened directory handle to open this file with,
// indicate that the program lacks the capabilities.
Expand All @@ -330,8 +308,7 @@ int
symlink(const char *target, const char *linkpath)
{
const char *relative_path;
int dirfd = __wasilibc_find_relpath(linkpath, __WASI_RIGHT_PATH_SYMLINK, 0,
&relative_path);
int dirfd = __wasilibc_find_relpath(linkpath, &relative_path);

// If we can't find a preopened directory handle to open this file with,
// indicate that the program lacks the capabilities.
Expand Down Expand Up @@ -359,10 +336,6 @@ struct po_map_entry {

/// File descriptor (which may be a directory)
int fd;

/// Capability rights associated with the file descriptor
__wasi_rights_t rights_base;
__wasi_rights_t rights_inheriting;
};

/// A vector of po_map_entry.
Expand Down Expand Up @@ -472,19 +445,10 @@ internal_register_preopened_fd(int fd, const char *name)
}
}

__wasi_fdstat_t statbuf;
int r = __wasi_fd_fdstat_get((__wasi_fd_t)fd, &statbuf);
if (r != 0) {
errno = r;
return -1; // TODO: Add an infallible way to get the rights?
}

struct po_map_entry *entry = &global_map.entries[global_map.length++];

entry->name = name;
entry->fd = fd;
entry->rights_base = statbuf.fs_rights_base;
entry->rights_inheriting = statbuf.fs_rights_inheriting;

po_map_assertvalid();

Expand All @@ -504,8 +468,6 @@ __wasilibc_register_preopened_fd(int fd, const char *path)
int
__wasilibc_find_relpath(
const char *path,
__wasi_rights_t rights_base,
__wasi_rights_t rights_inheriting,
const char **relative_path)
{
size_t bestlen = 0;
Expand Down Expand Up @@ -539,11 +501,6 @@ __wasilibc_find_relpath(
continue;
}

if ((rights_base & ~entry->rights_base) != 0 ||
(rights_inheriting & ~entry->rights_inheriting) != 0) {
continue;
}

best = entry->fd;
bestlen = len;
any_matches = true;
Expand Down

0 comments on commit 54102f0

Please sign in to comment.