authorgravatar for pat.github@tullmann.orgPat Tullmann <pat.github@tullmann.org> 2025-02-18 17:16:13-08:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-03-24 16:20:45+01:00
log02373eb2a59f4a16a06460c244958e236b1c5291
treed76d3dbdccbe37ac7728dd05e91888b8296eddaa
parentf304d8e50afac12ac209f850ced4f9ddf3bcff3b

lib/std/: WASI code should follow POSIX semantics for AccessDenied/PermissionDenied

Use error.AccessDenied for permissions (rights) failures on Wasi (`EACCES`) and error.PermissionDenied (`EPERM`) for systemic failures. And pass-through underlying Wasi errors (PermissionDenied or AccessDenied) without mapping.

2 files changed, 11 insertions(+), 16 deletions(-)

lib/std/fs/test.zig+1-1
......@@ -383,7 +383,7 @@ test "openDirAbsolute" {
383383
384384test "openDir cwd parent '..'" {
385385 var dir = fs.cwd().openDir("..", .{}) catch |err| {
386 if (native_os == .wasi and err == error.AccessDenied) {
386 if (native_os == .wasi and err == error.PermissionDenied) {
387387 return; // This is okay. WASI disallows escaping from the fs sandbox
388388 }
389389 return err;
lib/std/posix.zig+10-15
......@@ -1740,7 +1740,7 @@ pub fn openatWasi(
17401740 .NOMEM => return error.SystemResources,
17411741 .NOSPC => return error.NoSpaceLeft,
17421742 .NOTDIR => return error.NotDir,
1743 .PERM => return error.AccessDenied,
1743 .PERM => return error.PermissionDenied,
17441744 .EXIST => return error.PathAlreadyExists,
17451745 .BUSY => return error.DeviceBusy,
17461746 .NOTCAPABLE => return error.AccessDenied,
......@@ -2178,7 +2178,7 @@ pub fn symlinkatWasi(target_path: []const u8, newdirfd: fd_t, sym_link_path: []c
21782178 .INVAL => unreachable,
21792179 .BADF => unreachable,
21802180 .ACCES => return error.AccessDenied,
2181 .PERM => return error.AccessDenied,
2181 .PERM => return error.PermissionDenied,
21822182 .DQUOT => return error.DiskQuota,
21832183 .EXIST => return error.PathAlreadyExists,
21842184 .IO => return error.FileSystem,
......@@ -2502,7 +2502,7 @@ pub fn unlinkatWasi(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatErro
25022502 switch (res) {
25032503 .SUCCESS => return,
25042504 .ACCES => return error.AccessDenied,
2505 .PERM => return error.AccessDenied,
2505 .PERM => return error.PermissionDenied,
25062506 .BUSY => return error.FileBusy,
25072507 .FAULT => unreachable,
25082508 .IO => return error.FileSystem,
......@@ -2698,7 +2698,7 @@ fn renameatWasi(old: RelativePathWasi, new: RelativePathWasi) RenameError!void {
26982698 switch (wasi.path_rename(old.dir_fd, old.relative_path.ptr, old.relative_path.len, new.dir_fd, new.relative_path.ptr, new.relative_path.len)) {
26992699 .SUCCESS => return,
27002700 .ACCES => return error.AccessDenied,
2701 .PERM => return error.AccessDenied,
2701 .PERM => return error.PermissionDenied,
27022702 .BUSY => return error.FileBusy,
27032703 .DQUOT => return error.DiskQuota,
27042704 .FAULT => unreachable,
......@@ -2903,7 +2903,7 @@ pub fn mkdiratWasi(dir_fd: fd_t, sub_dir_path: []const u8, mode: mode_t) MakeDir
29032903 .SUCCESS => return,
29042904 .ACCES => return error.AccessDenied,
29052905 .BADF => unreachable,
2906 .PERM => return error.AccessDenied,
2906 .PERM => return error.PermissionDenied,
29072907 .DQUOT => return error.DiskQuota,
29082908 .EXIST => return error.PathAlreadyExists,
29092909 .FAULT => unreachable,
......@@ -4952,19 +4952,14 @@ pub fn faccessat(dirfd: fd_t, path: []const u8, mode: u32, flags: u32) AccessErr
49524952 } else if (native_os == .wasi and !builtin.link_libc) {
49534953 const resolved: RelativePathWasi = .{ .dir_fd = dirfd, .relative_path = path };
49544954
4955 const st = blk: {
4956 break :blk std.os.fstatat_wasi(dirfd, path, .{
4957 .SYMLINK_FOLLOW = (flags & AT.SYMLINK_NOFOLLOW) == 0,
4958 });
4959 } catch |err| switch (err) {
4960 error.AccessDenied => return error.PermissionDenied,
4961 else => |e| return e,
4962 };
4955 const st = try std.os.fstatat_wasi(dirfd, path, .{
4956 .SYMLINK_FOLLOW = (flags & AT.SYMLINK_NOFOLLOW) == 0,
4957 });
49634958
49644959 if (mode != F_OK) {
49654960 var directory: wasi.fdstat_t = undefined;
49664961 if (wasi.fd_fdstat_get(resolved.dir_fd, &directory) != .SUCCESS) {
4967 return error.PermissionDenied;
4962 return error.AccessDenied;
49684963 }
49694964
49704965 var rights: wasi.rights_t = .{};
......@@ -4984,7 +4979,7 @@ pub fn faccessat(dirfd: fd_t, path: []const u8, mode: u32, flags: u32) AccessErr
49844979 const rights_int: u64 = @bitCast(rights);
49854980 const inheriting_int: u64 = @bitCast(directory.fs_rights_inheriting);
49864981 if ((rights_int & inheriting_int) != rights_int) {
4987 return error.PermissionDenied;
4982 return error.AccessDenied;
49884983 }
49894984 }
49904985 return;