Skip to content

Commit

Permalink
add setup for new permissions APIs
Browse files Browse the repository at this point in the history
snapshot2 adds the following for working with file permissions:

- A permissions data type representing read, write,
  execute, and "private" permissions.
- path_permissions_set() which is similar to
  fchmodat().
- fd_permissions_set() which is similar to
  fchmod().
- Two new rights for calling the two new functions.
- A permissions field added to the filestat type.
- A permissions argument passed to path_open().

This will need to be verified against the wasi-libc once the
changes land there. Based on the auto-generated WASI docs, it
seems likely that existing constants will change/break.

Refs: #59
  • Loading branch information
cjihrig committed Jan 26, 2020
1 parent 7f6966c commit 72675d9
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 4 deletions.
96 changes: 96 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ This section has been adapted from the official WASI API documentation.
- [`uvwasi_fd_filestat_get()`](#fd_filestat_get)
- [`uvwasi_fd_filestat_set_size()`](#fd_filestat_set_size)
- [`uvwasi_fd_filestat_set_times()`](#fd_filestat_set_times)
- [`uvwasi_fd_permissions_set()`](#fd_permissions_set)
- [`uvwasi_fd_pread()`](#fd_pread)
- [`uvwasi_fd_prestat_get()`](#fd_prestat_get)
- [`uvwasi_fd_prestat_dir_name()`](#fd_prestat_dir_name)
Expand All @@ -218,6 +219,7 @@ This section has been adapted from the official WASI API documentation.
- [`uvwasi_path_filestat_set_times()`](#path_filestat_set_times)
- [`uvwasi_path_link()`](#path_link)
- [`uvwasi_path_open()`](#path_open)
- [`uvwasi_path_permissions_set()`](#path_permissions_set)
- [`uvwasi_path_readlink()`](#path_readlink)
- [`uvwasi_path_remove_directory()`](#path_remove_directory)
- [`uvwasi_path_rename()`](#path_rename)
Expand Down Expand Up @@ -512,6 +514,27 @@ Inputs:

A bitmask indicating which timestamps to adjust.

### <a href="#fd_permissions_set" name="fd_permissions_set"></a>`uvwasi_fd_permissions_set()`

Set the permissions of a file or directory.

This sets the permissions associated with a file or directory
in a filesystem at the time it is called. The ability to actually
access a file or directory may depend on additional permissions not
reflected here.

Note: This is similar `fchmod` in POSIX.

Inputs:

- <a href="#fd_permissions_set.fd" name="fd_permissions_set.fd"></a><code>[\_\_wasi\_fd\_t](#fd) <strong>fd</strong></code>

The file descriptor to operate on.

- <a href="#fd_permissions_set.permissions" name="fd_permissions_set.permissions"></a><code>[\_\_wasi\_permissions\_t](#permissions) <strong>permissions</strong></code>

The permissions associated with the file.

### <a href="#fd_pread" name="fd_pread"></a>`uvwasi_fd_pread()`

Read from a file descriptor, without using and updating the
Expand Down Expand Up @@ -908,13 +931,50 @@ Inputs:

The initial flags of the file descriptor.

- <a href="#path_open.permissions" name="path_open.permissions"></a><code>[\_\_wasi\_permissions\_t](#permissions) <strong>permissions</strong></code>

If a file is created, the filesystem permissions to associate with it.

Outputs:

- <a href="#path_open.fd" name="path_open.fd"></a><code>[\_\_wasi\_fd\_t](#fd) <strong>fd</strong></code>

The file descriptor of the file that has been
opened.

### <a href="#path_permissions_set" name="path_permissions_set"></a>`uvwasi_path_permissions_set()`

Set the permissions of a file or directory.

This sets the permissions associated with a file or directory in a
filesystem at the time it is called. The ability to actually access
a file or directory may depend on additional permissions not reflected
here.

Note: This is similar `fchmodat` in POSIX.

Unlike POSIX, this doesn't expose a user/group/other distinction;
implementations in POSIX environments are suggested to consult the
umask to determine which of the user/group/other flags to modify.

Inputs:

- <a href="#path_permissions_set.fd" name="path_permissions_set.fd"></a><code>[\_\_wasi\_fd\_t](#fd) <strong>fd</strong></code>

The file descriptor to operate on.

- <a href="#path_permissions_set.flags" name="path_permissions_set.flags"></a><code>[\_\_wasi\_lookupflags\_t](#lookupflags) <strong>flags</strong></code>

Flags determining the method of how the path is resolved.

- <a href="#path_permissions_set.path" name="path_permissions_set.path"></a><code>const char \*<strong>path</strong></code> and <a href="#path_permissions_set.path_len" name="path_permissions_set.path_len"></a><code>size\_t <strong>path\_len</strong></code>

The path to a file to query.

- <a href="#path_permissions_set.permissions" name="path_permissions_set.permissions"></a><code>[\_\_wasi\_permissions\_t](#permissions) <strong>permissions</strong></code>

The permissions associated with the file.

### <a href="#path_readlink" name="path_readlink"></a>`uvwasi_path_readlink()`

Read the contents of a symbolic link.
Expand Down Expand Up @@ -1790,6 +1850,10 @@ Members:

File type.

- <a href="#filestat.permissions" name="filestat.permissions"></a><code>[\_\_wasi\_permissions\_t](#permissions) <strong>permissions</strong></code>

File permissions.

- <a href="#filestat.st_nlink" name="filestat.st_nlink"></a><code>[\_\_wasi\_linkcount\_t](#linkcount) <strong>st\_nlink</strong></code>

Number of hard links to the file.
Expand Down Expand Up @@ -1952,6 +2016,30 @@ Possible values:

Truncate file to size 0.

### <a href="#permissions" name="permissions"></a>`uvwasi_permissions_t` (`uint8_t` bitfield)

File permissions. This represents the permissions associated with a file in a filesystem, and don't fully reflect all the conditions which determine whether a given WASI program can access the file.

Possible values:

- <a href="#permissions.read" name="permissions.read"></a>**`UVWASI_PERMISSION_READ`**

For files, permission to read the file. For directories, permission to do `readdir` and access files within the directory.

Note: This is similar to the read bit being set on files, and the read *and* execute bits being set on directories, in POSIX.

- <a href="#permissions.write" name="permissions.write"></a>**`UVWASI_PERMISSION_WRITE`**

For files, permission to mutate the file. For directories, permission to create, remove, and rename items within the directory.

- <a href="#permissions.execute" name="permissions.execute"></a>**`UVWASI_PERMISSION_EXECUTE`**

For files, permission to "execute" the file, using whatever concept of "executing" the host filesystem has. This flag is not valid for directories.

- <a href="#permissions.private" name="permissions.private"></a>**`UVWASI_PERMISSION_PRIVATE`**

For filesystems which have a concept of multiple "users", this flag indicates that the file is only accessible by the effective "user" that the WASI store uses to access the filesystem, and inaccessible to other "users".

### <a href="#riflags" name="riflags"></a>`uvwasi_riflags_t` (`uint16_t` bitfield)

Flags provided to [`uvwasi_sock_recv()`](#sock_recv).
Expand Down Expand Up @@ -2087,6 +2175,10 @@ Possible values:

The right to invoke [`uvwasi_path_filestat_set_times()`](#path_filestat_set_times).

- <a href="#rights.path_permissions_set" name="rights.path_permissions_set"></a>**`UVWASI_RIGHT_PATH_PERMISSIONS_SET`**

The right to invoke [`uvwasi_path_filestat_permissions_set()`](#path_filestat_permissions_set).

- <a href="#rights.fd_filestat_get" name="rights.fd_filestat_get"></a>**`UVWASI_RIGHT_FD_FILESTAT_GET`**

The right to invoke [`uvwasi_fd_filestat_get()`](#fd_filestat_get).
Expand All @@ -2099,6 +2191,10 @@ Possible values:

The right to invoke [`uvwasi_fd_filestat_set_times()`](#fd_filestat_set_times).

- <a href="#rights.fd_permissions_set" name="rights.fd_permissions_set"></a>**`UVWASI_RIGHT_FD_PERMISSIONS_SET`**

The right to invoke [`uvwasi_fd_filestat_permissions_set()`](#fd_filestat_permissions_set).

- <a href="#rights.path_symlink" name="rights.path_symlink"></a>**`UVWASI_RIGHT_PATH_SYMLINK`**

The right to invoke [`uvwasi_path_symlink()`](#path_symlink).
Expand Down
10 changes: 10 additions & 0 deletions include/uvwasi.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
uvwasi_timestamp_t st_atim,
uvwasi_timestamp_t st_mtim,
uvwasi_fstflags_t fst_flags);
uvwasi_errno_t uvwasi_fd_permissions_set(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_permissions_t permissions);
uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const uvwasi_iovec_t* iovs,
Expand Down Expand Up @@ -205,7 +208,14 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
uvwasi_rights_t fs_rights_base,
uvwasi_rights_t fs_rights_inheriting,
uvwasi_fdflags_t fs_flags,
uvwasi_permissions_t permissions,
uvwasi_fd_t* fd);
uvwasi_errno_t uvwasi_path_permissions_set(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_lookupflags_t flags,
const char* path,
size_t path_len,
uvwasi_permissions_t permissions);
uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
Expand Down
9 changes: 9 additions & 0 deletions include/wasi_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,18 @@ typedef uint64_t uvwasi_rights_t; /* Bitfield */
#define UVWASI_RIGHT_PATH_UNLINK_FILE (1 << 26)
#define UVWASI_RIGHT_POLL_FD_READWRITE (1 << 27)
#define UVWASI_RIGHT_SOCK_SHUTDOWN (1 << 28)
#define UVWASI_RIGHT_PATH_PERMISSIONS_SET (1 << 29)
#define UVWASI_RIGHT_FD_PERMISSIONS_SET (1 << 30)

typedef uint16_t uvwasi_roflags_t; /* Bitfield */
#define UVWASI_SOCK_RECV_DATA_TRUNCATED (1 << 0)

typedef uint8_t uvwasi_permissions_t; /* Bitfield */
#define UVWASI_PERMISSION_READ (1 << 0)
#define UVWASI_PERMISSION_WRITE (1 << 1)
#define UVWASI_PERMISSION_EXECUTE (1 << 2)
#define UVWASI_PERMISSION_PRIVATE (1 << 3)

typedef uint8_t uvwasi_sdflags_t; /* Bitfield */
#define UVWASI_SHUT_RD (1 << 0)
#define UVWASI_SHUT_WR (1 << 1)
Expand Down Expand Up @@ -264,6 +272,7 @@ typedef struct uvwasi_filestat_s {
uvwasi_device_t st_dev;
uvwasi_inode_t st_ino;
uvwasi_filetype_t st_filetype;
uvwasi_permissions_t permissions;
uvwasi_linkcount_t st_nlink;
uvwasi_filesize_t st_size;
uvwasi_timestamp_t st_atim;
Expand Down
2 changes: 2 additions & 0 deletions src/uv_mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ void uvwasi__stat_to_filestat(const uv_stat_t* stat, uvwasi_filestat_t* fs) {
fs->st_atim = uvwasi__timespec_to_timestamp(&stat->st_atim);
fs->st_mtim = uvwasi__timespec_to_timestamp(&stat->st_mtim);
fs->st_ctim = uvwasi__timespec_to_timestamp(&stat->st_ctim);
/* TODO(cjihrig): Permissions are not currently used. */
fs->permissions = 0;
}


Expand Down
28 changes: 28 additions & 0 deletions src/uvwasi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,17 @@ uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
}


uvwasi_errno_t uvwasi_fd_permissions_set(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_permissions_t permissions) {
if (uvwasi == NULL)
return UVWASI_EINVAL;

/* TODO(cjihrig): Implement this. */
return UVWASI_ENOTSUP;
}


uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const uvwasi_iovec_t* iovs,
Expand Down Expand Up @@ -1851,6 +1862,7 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
uvwasi_rights_t fs_rights_base,
uvwasi_rights_t fs_rights_inheriting,
uvwasi_fdflags_t fs_flags,
uvwasi_permissions_t permissions,
uvwasi_fd_t* fd) {
char resolved_path[PATH_MAX_BYTES];
uvwasi_rights_t needed_inheriting;
Expand All @@ -1867,6 +1879,8 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
int write;
int r;

/* TODO(cjihrig): The permissions input is currently not used. */

if (uvwasi == NULL || path == NULL || fd == NULL)
return UVWASI_EINVAL;

Expand Down Expand Up @@ -1982,6 +1996,20 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
}


uvwasi_errno_t uvwasi_path_permissions_set(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
uvwasi_lookupflags_t flags,
const char* path,
size_t path_len,
uvwasi_permissions_t permissions) {
if (uvwasi == NULL || path == NULL)
return UVWASI_EINVAL;

/* TODO(cjihrig): Implement this. */
return UVWASI_ENOTSUP;
}


uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
uvwasi_fd_t fd,
const char* path,
Expand Down
5 changes: 5 additions & 0 deletions src/wasi_rights.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@
UVWASI_RIGHT_PATH_FILESTAT_GET | \
UVWASI_RIGHT_PATH_FILESTAT_SET_SIZE | \
UVWASI_RIGHT_PATH_FILESTAT_SET_TIMES | \
UVWASI_RIGHT_PATH_PERMISSIONS_SET | \
UVWASI_RIGHT_FD_FILESTAT_GET | \
UVWASI_RIGHT_FD_FILESTAT_SET_TIMES | \
UVWASI_RIGHT_FD_FILESTAT_SET_SIZE | \
UVWASI_RIGHT_FD_PERMISSIONS_SET | \
UVWASI_RIGHT_PATH_SYMLINK | \
UVWASI_RIGHT_PATH_UNLINK_FILE | \
UVWASI_RIGHT_PATH_REMOVE_DIRECTORY | \
Expand All @@ -51,6 +53,7 @@
UVWASI_RIGHT_FD_FILESTAT_GET | \
UVWASI_RIGHT_FD_FILESTAT_SET_SIZE | \
UVWASI_RIGHT_FD_FILESTAT_SET_TIMES |\
UVWASI_RIGHT_FD_PERMISSIONS_SET | \
UVWASI_RIGHT_POLL_FD_READWRITE)
#define UVWASI__RIGHTS_REGULAR_FILE_INHERITING 0

Expand All @@ -69,8 +72,10 @@
UVWASI_RIGHT_PATH_FILESTAT_GET | \
UVWASI_RIGHT_PATH_FILESTAT_SET_SIZE | \
UVWASI_RIGHT_PATH_FILESTAT_SET_TIMES | \
UVWASI_RIGHT_PATH_PERMISSIONS_SET | \
UVWASI_RIGHT_FD_FILESTAT_GET | \
UVWASI_RIGHT_FD_FILESTAT_SET_TIMES | \
UVWASI_RIGHT_FD_PERMISSIONS_SET | \
UVWASI_RIGHT_PATH_SYMLINK | \
UVWASI_RIGHT_PATH_UNLINK_FILE | \
UVWASI_RIGHT_PATH_REMOVE_DIRECTORY | \
Expand Down
3 changes: 3 additions & 0 deletions test/test-basic-file-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ int main(void) {
fs_rights_base,
0,
0,
0,
&fd);
assert(err == 0);

Expand All @@ -79,6 +80,7 @@ int main(void) {
assert(stats.st_atim > 0);
assert(stats.st_mtim > 0);
assert(stats.st_ctim > 0);
assert(stats.permissions == 0);

/* Resize the file to 1024 bytes. */
err = uvwasi_fd_filestat_set_size(&uvwasi, fd, 1024);
Expand Down Expand Up @@ -163,6 +165,7 @@ int main(void) {
assert(stats2.st_atim > 0);
assert(stats2.st_mtim > 0);
assert(stats2.st_ctim > 0);
assert(stats2.permissions == 0);

/* Unlink the file. */
err = uvwasi_path_unlink_file(&uvwasi, 3, path, strlen(path) + 1);
Expand Down
2 changes: 1 addition & 1 deletion test/test-ebadf-input-validation.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ int main(void) {
CHECK(uvwasi_path_filestat_get(&uvw, 100, 0, test_str, 5, &test_filestat));
CHECK(uvwasi_path_filestat_set_times(&uvw, 100, 0, test_str, 4, 5, 6, 7));
CHECK(uvwasi_path_link(&uvw, 100, 4, test_str, 5, 100, test_str, 6));
CHECK(uvwasi_path_open(&uvw, 100, 0, test_str, 4, 5, 6, 7, 8, &test_fd));
CHECK(uvwasi_path_open(&uvw, 100, 0, test_str, 4, 5, 6, 7, 8, 9, &test_fd));
CHECK(uvwasi_path_readlink(&uvw, 100, test_str, 4, test_str, 5, &test_size));
CHECK(uvwasi_path_remove_directory(&uvw, 99, "x", 2));
CHECK(uvwasi_path_rename(&uvw, 99, test_str, 4, 99, test_str, 5));
Expand Down
11 changes: 8 additions & 3 deletions test/test-einval-input-validation.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ int main(void) {

CHECK(uvwasi_fd_filestat_set_times(NULL, 3, 0, 0, UVWASI_FILESTAT_SET_ATIM));

CHECK(uvwasi_fd_permissions_set(NULL, 3, 0));

CHECK(uvwasi_fd_pread(NULL, 3, &test_iovec, 2, 10, &test_size));
CHECK(uvwasi_fd_pread(&uvw, 3, NULL, 2, 10, &test_size));
CHECK(uvwasi_fd_pread(&uvw, 3, &test_iovec, 2, 10, NULL));
Expand Down Expand Up @@ -124,9 +126,12 @@ int main(void) {
CHECK(uvwasi_path_link(&uvw, 3, 4, NULL, 5, 3, test_str, 6));
CHECK(uvwasi_path_link(&uvw, 3, 4, test_str, 5, 3, NULL, 6));

CHECK(uvwasi_path_open(NULL, 3, 0, test_str, 4, 5, 6, 7, 8, &test_fd));
CHECK(uvwasi_path_open(&uvw, 3, 0, NULL, 4, 5, 6, 7, 8, &test_fd));
CHECK(uvwasi_path_open(&uvw, 3, 0, test_str, 4, 5, 6, 7, 8, NULL));
CHECK(uvwasi_path_open(NULL, 3, 0, test_str, 4, 5, 6, 7, 8, 9, &test_fd));
CHECK(uvwasi_path_open(&uvw, 3, 0, NULL, 4, 5, 6, 7, 8, 9, &test_fd));
CHECK(uvwasi_path_open(&uvw, 3, 0, test_str, 4, 5, 6, 7, 8, 9, NULL));

CHECK(uvwasi_path_permissions_set(NULL, 3, 1, test_str, 4, 5));
CHECK(uvwasi_path_permissions_set(&uvw, 3, 1, NULL, 4, 5));

CHECK(uvwasi_path_readlink(NULL, 3, test_str, 4, test_str, 5, &test_size));
CHECK(uvwasi_path_readlink(&uvw, 3, NULL, 4, test_str, 5, &test_size));
Expand Down

0 comments on commit 72675d9

Please sign in to comment.