Skip to content

Commit 5fc0b7e

Browse files
committed
add setup for new permissions APIs
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
1 parent 1243e5e commit 5fc0b7e

10 files changed

+225
-5
lines changed

README.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ This section has been adapted from the official WASI API documentation.
221221
- [`uvwasi_fd_filestat_get()`](#fd_filestat_get)
222222
- [`uvwasi_fd_filestat_set_size()`](#fd_filestat_set_size)
223223
- [`uvwasi_fd_filestat_set_times()`](#fd_filestat_set_times)
224+
- [`uvwasi_fd_permissions_set()`](#fd_permissions_set)
224225
- [`uvwasi_fd_pread()`](#fd_pread)
225226
- [`uvwasi_fd_prestat_get()`](#fd_prestat_get)
226227
- [`uvwasi_fd_prestat_dir_name()`](#fd_prestat_dir_name)
@@ -237,6 +238,7 @@ This section has been adapted from the official WASI API documentation.
237238
- [`uvwasi_path_filestat_set_times()`](#path_filestat_set_times)
238239
- [`uvwasi_path_link()`](#path_link)
239240
- [`uvwasi_path_open()`](#path_open)
241+
- [`uvwasi_path_permissions_set()`](#path_permissions_set)
240242
- [`uvwasi_path_readlink()`](#path_readlink)
241243
- [`uvwasi_path_remove_directory()`](#path_remove_directory)
242244
- [`uvwasi_path_rename()`](#path_rename)
@@ -531,6 +533,27 @@ Inputs:
531533

532534
A bitmask indicating which timestamps to adjust.
533535

536+
### <a href="#fd_permissions_set" name="fd_permissions_set"></a>`uvwasi_fd_permissions_set()`
537+
538+
Set the permissions of a file or directory.
539+
540+
This sets the permissions associated with a file or directory
541+
in a filesystem at the time it is called. The ability to actually
542+
access a file or directory may depend on additional permissions not
543+
reflected here.
544+
545+
Note: This is similar `fchmod` in POSIX.
546+
547+
Inputs:
548+
549+
- <a href="#fd_permissions_set.fd" name="fd_permissions_set.fd"></a><code>[\_\_wasi\_fd\_t](#fd) <strong>fd</strong></code>
550+
551+
The file descriptor to operate on.
552+
553+
- <a href="#fd_permissions_set.permissions" name="fd_permissions_set.permissions"></a><code>[\_\_wasi\_permissions\_t](#permissions) <strong>permissions</strong></code>
554+
555+
The permissions associated with the file.
556+
534557
### <a href="#fd_pread" name="fd_pread"></a>`uvwasi_fd_pread()`
535558

536559
Read from a file descriptor, without using and updating the
@@ -927,13 +950,50 @@ Inputs:
927950

928951
The initial flags of the file descriptor.
929952

953+
- <a href="#path_open.permissions" name="path_open.permissions"></a><code>[\_\_wasi\_permissions\_t](#permissions) <strong>permissions</strong></code>
954+
955+
If a file is created, the filesystem permissions to associate with it.
956+
930957
Outputs:
931958

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

934961
The file descriptor of the file that has been
935962
opened.
936963

964+
### <a href="#path_permissions_set" name="path_permissions_set"></a>`uvwasi_path_permissions_set()`
965+
966+
Set the permissions of a file or directory.
967+
968+
This sets the permissions associated with a file or directory in a
969+
filesystem at the time it is called. The ability to actually access
970+
a file or directory may depend on additional permissions not reflected
971+
here.
972+
973+
Note: This is similar `fchmodat` in POSIX.
974+
975+
Unlike POSIX, this doesn't expose a user/group/other distinction;
976+
implementations in POSIX environments are suggested to consult the
977+
umask to determine which of the user/group/other flags to modify.
978+
979+
Inputs:
980+
981+
- <a href="#path_permissions_set.fd" name="path_permissions_set.fd"></a><code>[\_\_wasi\_fd\_t](#fd) <strong>fd</strong></code>
982+
983+
The file descriptor to operate on.
984+
985+
- <a href="#path_permissions_set.flags" name="path_permissions_set.flags"></a><code>[\_\_wasi\_lookupflags\_t](#lookupflags) <strong>flags</strong></code>
986+
987+
Flags determining the method of how the path is resolved.
988+
989+
- <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>
990+
991+
The path to a file to query.
992+
993+
- <a href="#path_permissions_set.permissions" name="path_permissions_set.permissions"></a><code>[\_\_wasi\_permissions\_t](#permissions) <strong>permissions</strong></code>
994+
995+
The permissions associated with the file.
996+
937997
### <a href="#path_readlink" name="path_readlink"></a>`uvwasi_path_readlink()`
938998

939999
Read the contents of a symbolic link.
@@ -1809,6 +1869,10 @@ Members:
18091869

18101870
File type.
18111871

1872+
- <a href="#filestat.permissions" name="filestat.permissions"></a><code>[\_\_wasi\_permissions\_t](#permissions) <strong>permissions</strong></code>
1873+
1874+
File permissions.
1875+
18121876
- <a href="#filestat.st_nlink" name="filestat.st_nlink"></a><code>[\_\_wasi\_linkcount\_t](#linkcount) <strong>st\_nlink</strong></code>
18131877

18141878
Number of hard links to the file.
@@ -1971,6 +2035,30 @@ Possible values:
19712035

19722036
Truncate file to size 0.
19732037

2038+
### <a href="#permissions" name="permissions"></a>`uvwasi_permissions_t` (`uint8_t` bitfield)
2039+
2040+
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.
2041+
2042+
Possible values:
2043+
2044+
- <a href="#permissions.read" name="permissions.read"></a>**`UVWASI_PERMISSION_READ`**
2045+
2046+
For files, permission to read the file. For directories, permission to do `readdir` and access files within the directory.
2047+
2048+
Note: This is similar to the read bit being set on files, and the read *and* execute bits being set on directories, in POSIX.
2049+
2050+
- <a href="#permissions.write" name="permissions.write"></a>**`UVWASI_PERMISSION_WRITE`**
2051+
2052+
For files, permission to mutate the file. For directories, permission to create, remove, and rename items within the directory.
2053+
2054+
- <a href="#permissions.execute" name="permissions.execute"></a>**`UVWASI_PERMISSION_EXECUTE`**
2055+
2056+
For files, permission to "execute" the file, using whatever concept of "executing" the host filesystem has. This flag is not valid for directories.
2057+
2058+
- <a href="#permissions.private" name="permissions.private"></a>**`UVWASI_PERMISSION_PRIVATE`**
2059+
2060+
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".
2061+
19742062
### <a href="#riflags" name="riflags"></a>`uvwasi_riflags_t` (`uint16_t` bitfield)
19752063

19762064
Flags provided to [`uvwasi_sock_recv()`](#sock_recv).
@@ -2106,6 +2194,10 @@ Possible values:
21062194

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

2197+
- <a href="#rights.path_permissions_set" name="rights.path_permissions_set"></a>**`UVWASI_RIGHT_PATH_PERMISSIONS_SET`**
2198+
2199+
The right to invoke [`uvwasi_path_filestat_permissions_set()`](#path_filestat_permissions_set).
2200+
21092201
- <a href="#rights.fd_filestat_get" name="rights.fd_filestat_get"></a>**`UVWASI_RIGHT_FD_FILESTAT_GET`**
21102202

21112203
The right to invoke [`uvwasi_fd_filestat_get()`](#fd_filestat_get).
@@ -2118,6 +2210,10 @@ Possible values:
21182210

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

2213+
- <a href="#rights.fd_permissions_set" name="rights.fd_permissions_set"></a>**`UVWASI_RIGHT_FD_PERMISSIONS_SET`**
2214+
2215+
The right to invoke [`uvwasi_fd_filestat_permissions_set()`](#fd_filestat_permissions_set).
2216+
21212217
- <a href="#rights.path_symlink" name="rights.path_symlink"></a>**`UVWASI_RIGHT_PATH_SYMLINK`**
21222218

21232219
The right to invoke [`uvwasi_path_symlink()`](#path_symlink).

include/uvwasi.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
126126
uvwasi_timestamp_t st_atim,
127127
uvwasi_timestamp_t st_mtim,
128128
uvwasi_fstflags_t fst_flags);
129+
uvwasi_errno_t uvwasi_fd_permissions_set(uvwasi_t* uvwasi,
130+
uvwasi_fd_t fd,
131+
uvwasi_permissions_t permissions);
129132
uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
130133
uvwasi_fd_t fd,
131134
const uvwasi_iovec_t* iovs,
@@ -208,7 +211,14 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
208211
uvwasi_rights_t fs_rights_base,
209212
uvwasi_rights_t fs_rights_inheriting,
210213
uvwasi_fdflags_t fs_flags,
214+
uvwasi_permissions_t permissions,
211215
uvwasi_fd_t* fd);
216+
uvwasi_errno_t uvwasi_path_permissions_set(uvwasi_t* uvwasi,
217+
uvwasi_fd_t fd,
218+
uvwasi_lookupflags_t flags,
219+
const char* path,
220+
size_t path_len,
221+
uvwasi_permissions_t permissions);
212222
uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
213223
uvwasi_fd_t fd,
214224
const char* path,

include/wasi_types.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,18 @@ typedef uint64_t uvwasi_rights_t; /* Bitfield */
213213
#define UVWASI_RIGHT_PATH_UNLINK_FILE (1 << 26)
214214
#define UVWASI_RIGHT_POLL_FD_READWRITE (1 << 27)
215215
#define UVWASI_RIGHT_SOCK_SHUTDOWN (1 << 28)
216+
#define UVWASI_RIGHT_PATH_PERMISSIONS_SET (1 << 29)
217+
#define UVWASI_RIGHT_FD_PERMISSIONS_SET (1 << 30)
216218

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

222+
typedef uint8_t uvwasi_permissions_t; /* Bitfield */
223+
#define UVWASI_PERMISSION_READ (1 << 0)
224+
#define UVWASI_PERMISSION_WRITE (1 << 1)
225+
#define UVWASI_PERMISSION_EXECUTE (1 << 2)
226+
#define UVWASI_PERMISSION_PRIVATE (1 << 3)
227+
220228
typedef uint8_t uvwasi_sdflags_t; /* Bitfield */
221229
#define UVWASI_SHUT_RD (1 << 0)
222230
#define UVWASI_SHUT_WR (1 << 1)
@@ -264,6 +272,7 @@ typedef struct uvwasi_filestat_s {
264272
uvwasi_device_t st_dev;
265273
uvwasi_inode_t st_ino;
266274
uvwasi_filetype_t st_filetype;
275+
uvwasi_permissions_t permissions;
267276
uvwasi_linkcount_t st_nlink;
268277
uvwasi_filesize_t st_size;
269278
uvwasi_timestamp_t st_atim;

src/uv_mapping.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,14 @@ void uvwasi__stat_to_filestat(const uv_stat_t* stat, uvwasi_filestat_t* fs) {
155155
fs->st_atim = uvwasi__timespec_to_timestamp(&stat->st_atim);
156156
fs->st_mtim = uvwasi__timespec_to_timestamp(&stat->st_mtim);
157157
fs->st_ctim = uvwasi__timespec_to_timestamp(&stat->st_ctim);
158+
/* TODO(cjihrig): Permissions are not currently used. */
159+
fs->permissions = 0;
160+
}
161+
162+
163+
void uvwasi__permissions_to_mode(const uvwasi_permissions_t permissions,
164+
int* mode) {
165+
*mode = 0666; /* TODO(cjihrig): Parse this from permissions argument. */
158166
}
159167

160168

src/uv_mapping.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ uvwasi_errno_t uvwasi__translate_uv_error(int err);
1010
uvwasi_timestamp_t uvwasi__timespec_to_timestamp(const uv_timespec_t* ts);
1111
uvwasi_filetype_t uvwasi__stat_to_filetype(const uv_stat_t* stat);
1212
void uvwasi__stat_to_filestat(const uv_stat_t* stat, uvwasi_filestat_t* fs);
13+
void uvwasi__permissions_to_mode(const uvwasi_permissions_t permissions,
14+
int* mode);
1315
uvwasi_errno_t uvwasi__get_filetype_by_fd(uv_file fd, uvwasi_filetype_t* type);
1416

1517
#endif /* __UVWASI_UV_MAPPING_H__ */

src/uvwasi.c

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1178,6 +1178,38 @@ uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
11781178
}
11791179

11801180

1181+
uvwasi_errno_t uvwasi_fd_permissions_set(uvwasi_t* uvwasi,
1182+
uvwasi_fd_t fd,
1183+
uvwasi_permissions_t permissions) {
1184+
struct uvwasi_fd_wrap_t* wrap;
1185+
uv_fs_t req;
1186+
uvwasi_errno_t err;
1187+
int mode;
1188+
int r;
1189+
1190+
if (uvwasi == NULL)
1191+
return UVWASI_EINVAL;
1192+
1193+
uvwasi__permissions_to_mode(permissions, &mode);
1194+
err = uvwasi_fd_table_get(&uvwasi->fds,
1195+
fd,
1196+
&wrap,
1197+
UVWASI_RIGHT_FD_PERMISSIONS_SET,
1198+
0);
1199+
if (err != UVWASI_ESUCCESS)
1200+
return err;
1201+
1202+
r = uv_fs_fchmod(NULL, &req, wrap->fd, mode, NULL);
1203+
uv_mutex_unlock(&wrap->mutex);
1204+
uv_fs_req_cleanup(&req);
1205+
1206+
if (r != 0)
1207+
return uvwasi__translate_uv_error(r);
1208+
1209+
return UVWASI_ESUCCESS;
1210+
}
1211+
1212+
11811213
uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
11821214
uvwasi_fd_t fd,
11831215
const uvwasi_iovec_t* iovs,
@@ -1864,6 +1896,7 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
18641896
uvwasi_rights_t fs_rights_base,
18651897
uvwasi_rights_t fs_rights_inheriting,
18661898
uvwasi_fdflags_t fs_flags,
1899+
uvwasi_permissions_t permissions,
18671900
uvwasi_fd_t* fd) {
18681901
char resolved_path[PATH_MAX_BYTES];
18691902
uvwasi_rights_t needed_inheriting;
@@ -1878,11 +1911,13 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
18781911
int flags;
18791912
int read;
18801913
int write;
1914+
int mode;
18811915
int r;
18821916

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

1920+
uvwasi__permissions_to_mode(permissions, &mode);
18861921
read = 0 != (fs_rights_base & (UVWASI_RIGHT_FD_READ |
18871922
UVWASI_RIGHT_FD_READDIR));
18881923
write = 0 != (fs_rights_base & (UVWASI_RIGHT_FD_DATASYNC |
@@ -1948,7 +1983,7 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
19481983
return err;
19491984
}
19501985

1951-
r = uv_fs_open(NULL, &req, resolved_path, flags, 0666, NULL);
1986+
r = uv_fs_open(NULL, &req, resolved_path, flags, mode, NULL);
19521987
uv_mutex_unlock(&dirfd_wrap->mutex);
19531988
uv_fs_req_cleanup(&req);
19541989

@@ -1995,6 +2030,53 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
19952030
}
19962031

19972032

2033+
uvwasi_errno_t uvwasi_path_permissions_set(uvwasi_t* uvwasi,
2034+
uvwasi_fd_t fd,
2035+
uvwasi_lookupflags_t flags,
2036+
const char* path,
2037+
size_t path_len,
2038+
uvwasi_permissions_t permissions) {
2039+
char resolved_path[PATH_MAX_BYTES];
2040+
struct uvwasi_fd_wrap_t* wrap;
2041+
uv_fs_t req;
2042+
uvwasi_errno_t err;
2043+
int mode;
2044+
int r;
2045+
2046+
if (uvwasi == NULL || path == NULL)
2047+
return UVWASI_EINVAL;
2048+
2049+
uvwasi__permissions_to_mode(permissions, &mode);
2050+
err = uvwasi_fd_table_get(&uvwasi->fds,
2051+
fd,
2052+
&wrap,
2053+
UVWASI_RIGHT_PATH_PERMISSIONS_SET,
2054+
0);
2055+
if (err != UVWASI_ESUCCESS)
2056+
return err;
2057+
2058+
err = uvwasi__resolve_path(uvwasi,
2059+
wrap,
2060+
path,
2061+
path_len,
2062+
resolved_path,
2063+
flags);
2064+
if (err != UVWASI_ESUCCESS) {
2065+
uv_mutex_unlock(&wrap->mutex);
2066+
return err;
2067+
}
2068+
2069+
r = uv_fs_chmod(NULL, &req, resolved_path, mode, NULL);
2070+
uv_mutex_unlock(&wrap->mutex);
2071+
uv_fs_req_cleanup(&req);
2072+
2073+
if (r != 0)
2074+
return uvwasi__translate_uv_error(r);
2075+
2076+
return UVWASI_ESUCCESS;
2077+
}
2078+
2079+
19982080
uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
19992081
uvwasi_fd_t fd,
20002082
const char* path,

src/wasi_rights.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@
2424
UVWASI_RIGHT_PATH_FILESTAT_GET | \
2525
UVWASI_RIGHT_PATH_FILESTAT_SET_SIZE | \
2626
UVWASI_RIGHT_PATH_FILESTAT_SET_TIMES | \
27+
UVWASI_RIGHT_PATH_PERMISSIONS_SET | \
2728
UVWASI_RIGHT_FD_FILESTAT_GET | \
2829
UVWASI_RIGHT_FD_FILESTAT_SET_TIMES | \
2930
UVWASI_RIGHT_FD_FILESTAT_SET_SIZE | \
31+
UVWASI_RIGHT_FD_PERMISSIONS_SET | \
3032
UVWASI_RIGHT_PATH_SYMLINK | \
3133
UVWASI_RIGHT_PATH_UNLINK_FILE | \
3234
UVWASI_RIGHT_PATH_REMOVE_DIRECTORY | \
@@ -51,6 +53,7 @@
5153
UVWASI_RIGHT_FD_FILESTAT_GET | \
5254
UVWASI_RIGHT_FD_FILESTAT_SET_SIZE | \
5355
UVWASI_RIGHT_FD_FILESTAT_SET_TIMES |\
56+
UVWASI_RIGHT_FD_PERMISSIONS_SET | \
5457
UVWASI_RIGHT_POLL_FD_READWRITE)
5558
#define UVWASI__RIGHTS_REGULAR_FILE_INHERITING 0
5659

@@ -69,8 +72,10 @@
6972
UVWASI_RIGHT_PATH_FILESTAT_GET | \
7073
UVWASI_RIGHT_PATH_FILESTAT_SET_SIZE | \
7174
UVWASI_RIGHT_PATH_FILESTAT_SET_TIMES | \
75+
UVWASI_RIGHT_PATH_PERMISSIONS_SET | \
7276
UVWASI_RIGHT_FD_FILESTAT_GET | \
7377
UVWASI_RIGHT_FD_FILESTAT_SET_TIMES | \
78+
UVWASI_RIGHT_FD_PERMISSIONS_SET | \
7479
UVWASI_RIGHT_PATH_SYMLINK | \
7580
UVWASI_RIGHT_PATH_UNLINK_FILE | \
7681
UVWASI_RIGHT_PATH_REMOVE_DIRECTORY | \

0 commit comments

Comments
 (0)