Skip to content

Commit 664a847

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 e3c85d4 commit 664a847

10 files changed

+225
-5
lines changed

README.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ This section has been adapted from the official WASI API documentation.
213213
- [`uvwasi_fd_filestat_get()`](#fd_filestat_get)
214214
- [`uvwasi_fd_filestat_set_size()`](#fd_filestat_set_size)
215215
- [`uvwasi_fd_filestat_set_times()`](#fd_filestat_set_times)
216+
- [`uvwasi_fd_permissions_set()`](#fd_permissions_set)
216217
- [`uvwasi_fd_pread()`](#fd_pread)
217218
- [`uvwasi_fd_prestat_get()`](#fd_prestat_get)
218219
- [`uvwasi_fd_prestat_dir_name()`](#fd_prestat_dir_name)
@@ -229,6 +230,7 @@ This section has been adapted from the official WASI API documentation.
229230
- [`uvwasi_path_filestat_set_times()`](#path_filestat_set_times)
230231
- [`uvwasi_path_link()`](#path_link)
231232
- [`uvwasi_path_open()`](#path_open)
233+
- [`uvwasi_path_permissions_set()`](#path_permissions_set)
232234
- [`uvwasi_path_readlink()`](#path_readlink)
233235
- [`uvwasi_path_remove_directory()`](#path_remove_directory)
234236
- [`uvwasi_path_rename()`](#path_rename)
@@ -523,6 +525,27 @@ Inputs:
523525

524526
A bitmask indicating which timestamps to adjust.
525527

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

528551
Read from a file descriptor, without using and updating the
@@ -919,13 +942,50 @@ Inputs:
919942

920943
The initial flags of the file descriptor.
921944

945+
- <a href="#path_open.permissions" name="path_open.permissions"></a><code>[\_\_wasi\_permissions\_t](#permissions) <strong>permissions</strong></code>
946+
947+
If a file is created, the filesystem permissions to associate with it.
948+
922949
Outputs:
923950

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

926953
The file descriptor of the file that has been
927954
opened.
928955

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

931991
Read the contents of a symbolic link.
@@ -1801,6 +1861,10 @@ Members:
18011861

18021862
File type.
18031863

1864+
- <a href="#filestat.permissions" name="filestat.permissions"></a><code>[\_\_wasi\_permissions\_t](#permissions) <strong>permissions</strong></code>
1865+
1866+
File permissions.
1867+
18041868
- <a href="#filestat.st_nlink" name="filestat.st_nlink"></a><code>[\_\_wasi\_linkcount\_t](#linkcount) <strong>st\_nlink</strong></code>
18051869

18061870
Number of hard links to the file.
@@ -1963,6 +2027,30 @@ Possible values:
19632027

19642028
Truncate file to size 0.
19652029

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

19682056
Flags provided to [`uvwasi_sock_recv()`](#sock_recv).
@@ -2098,6 +2186,10 @@ Possible values:
20982186

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

2189+
- <a href="#rights.path_permissions_set" name="rights.path_permissions_set"></a>**`UVWASI_RIGHT_PATH_PERMISSIONS_SET`**
2190+
2191+
The right to invoke [`uvwasi_path_filestat_permissions_set()`](#path_filestat_permissions_set).
2192+
21012193
- <a href="#rights.fd_filestat_get" name="rights.fd_filestat_get"></a>**`UVWASI_RIGHT_FD_FILESTAT_GET`**
21022194

21032195
The right to invoke [`uvwasi_fd_filestat_get()`](#fd_filestat_get).
@@ -2110,6 +2202,10 @@ Possible values:
21102202

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

2205+
- <a href="#rights.fd_permissions_set" name="rights.fd_permissions_set"></a>**`UVWASI_RIGHT_FD_PERMISSIONS_SET`**
2206+
2207+
The right to invoke [`uvwasi_fd_filestat_permissions_set()`](#fd_filestat_permissions_set).
2208+
21132209
- <a href="#rights.path_symlink" name="rights.path_symlink"></a>**`UVWASI_RIGHT_PATH_SYMLINK`**
21142210

21152211
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
@@ -123,6 +123,9 @@ uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
123123
uvwasi_timestamp_t st_atim,
124124
uvwasi_timestamp_t st_mtim,
125125
uvwasi_fstflags_t fst_flags);
126+
uvwasi_errno_t uvwasi_fd_permissions_set(uvwasi_t* uvwasi,
127+
uvwasi_fd_t fd,
128+
uvwasi_permissions_t permissions);
126129
uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
127130
uvwasi_fd_t fd,
128131
const uvwasi_iovec_t* iovs,
@@ -205,7 +208,14 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
205208
uvwasi_rights_t fs_rights_base,
206209
uvwasi_rights_t fs_rights_inheriting,
207210
uvwasi_fdflags_t fs_flags,
211+
uvwasi_permissions_t permissions,
208212
uvwasi_fd_t* fd);
213+
uvwasi_errno_t uvwasi_path_permissions_set(uvwasi_t* uvwasi,
214+
uvwasi_fd_t fd,
215+
uvwasi_lookupflags_t flags,
216+
const char* path,
217+
size_t path_len,
218+
uvwasi_permissions_t permissions);
209219
uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
210220
uvwasi_fd_t fd,
211221
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
@@ -1170,6 +1170,38 @@ uvwasi_errno_t uvwasi_fd_filestat_set_times(uvwasi_t* uvwasi,
11701170
}
11711171

11721172

1173+
uvwasi_errno_t uvwasi_fd_permissions_set(uvwasi_t* uvwasi,
1174+
uvwasi_fd_t fd,
1175+
uvwasi_permissions_t permissions) {
1176+
struct uvwasi_fd_wrap_t* wrap;
1177+
uv_fs_t req;
1178+
uvwasi_errno_t err;
1179+
int mode;
1180+
int r;
1181+
1182+
if (uvwasi == NULL)
1183+
return UVWASI_EINVAL;
1184+
1185+
uvwasi__permissions_to_mode(permissions, &mode);
1186+
err = uvwasi_fd_table_get(&uvwasi->fds,
1187+
fd,
1188+
&wrap,
1189+
UVWASI_RIGHT_FD_PERMISSIONS_SET,
1190+
0);
1191+
if (err != UVWASI_ESUCCESS)
1192+
return err;
1193+
1194+
r = uv_fs_fchmod(NULL, &req, wrap->fd, mode, NULL);
1195+
uv_mutex_unlock(&wrap->mutex);
1196+
uv_fs_req_cleanup(&req);
1197+
1198+
if (r != 0)
1199+
return uvwasi__translate_uv_error(r);
1200+
1201+
return UVWASI_ESUCCESS;
1202+
}
1203+
1204+
11731205
uvwasi_errno_t uvwasi_fd_pread(uvwasi_t* uvwasi,
11741206
uvwasi_fd_t fd,
11751207
const uvwasi_iovec_t* iovs,
@@ -1856,6 +1888,7 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
18561888
uvwasi_rights_t fs_rights_base,
18571889
uvwasi_rights_t fs_rights_inheriting,
18581890
uvwasi_fdflags_t fs_flags,
1891+
uvwasi_permissions_t permissions,
18591892
uvwasi_fd_t* fd) {
18601893
char resolved_path[PATH_MAX_BYTES];
18611894
uvwasi_rights_t needed_inheriting;
@@ -1870,11 +1903,13 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
18701903
int flags;
18711904
int read;
18721905
int write;
1906+
int mode;
18731907
int r;
18741908

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

1912+
uvwasi__permissions_to_mode(permissions, &mode);
18781913
read = 0 != (fs_rights_base & (UVWASI_RIGHT_FD_READ |
18791914
UVWASI_RIGHT_FD_READDIR));
18801915
write = 0 != (fs_rights_base & (UVWASI_RIGHT_FD_DATASYNC |
@@ -1940,7 +1975,7 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
19401975
return err;
19411976
}
19421977

1943-
r = uv_fs_open(NULL, &req, resolved_path, flags, 0666, NULL);
1978+
r = uv_fs_open(NULL, &req, resolved_path, flags, mode, NULL);
19441979
uv_mutex_unlock(&dirfd_wrap->mutex);
19451980
uv_fs_req_cleanup(&req);
19461981

@@ -1987,6 +2022,53 @@ uvwasi_errno_t uvwasi_path_open(uvwasi_t* uvwasi,
19872022
}
19882023

19892024

2025+
uvwasi_errno_t uvwasi_path_permissions_set(uvwasi_t* uvwasi,
2026+
uvwasi_fd_t fd,
2027+
uvwasi_lookupflags_t flags,
2028+
const char* path,
2029+
size_t path_len,
2030+
uvwasi_permissions_t permissions) {
2031+
char resolved_path[PATH_MAX_BYTES];
2032+
struct uvwasi_fd_wrap_t* wrap;
2033+
uv_fs_t req;
2034+
uvwasi_errno_t err;
2035+
int mode;
2036+
int r;
2037+
2038+
if (uvwasi == NULL || path == NULL)
2039+
return UVWASI_EINVAL;
2040+
2041+
uvwasi__permissions_to_mode(permissions, &mode);
2042+
err = uvwasi_fd_table_get(&uvwasi->fds,
2043+
fd,
2044+
&wrap,
2045+
UVWASI_RIGHT_PATH_PERMISSIONS_SET,
2046+
0);
2047+
if (err != UVWASI_ESUCCESS)
2048+
return err;
2049+
2050+
err = uvwasi__resolve_path(uvwasi,
2051+
wrap,
2052+
path,
2053+
path_len,
2054+
resolved_path,
2055+
flags);
2056+
if (err != UVWASI_ESUCCESS) {
2057+
uv_mutex_unlock(&wrap->mutex);
2058+
return err;
2059+
}
2060+
2061+
r = uv_fs_chmod(NULL, &req, resolved_path, mode, NULL);
2062+
uv_mutex_unlock(&wrap->mutex);
2063+
uv_fs_req_cleanup(&req);
2064+
2065+
if (r != 0)
2066+
return uvwasi__translate_uv_error(r);
2067+
2068+
return UVWASI_ESUCCESS;
2069+
}
2070+
2071+
19902072
uvwasi_errno_t uvwasi_path_readlink(uvwasi_t* uvwasi,
19912073
uvwasi_fd_t fd,
19922074
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)