Commit 7e63f7ad03

Andreas Linz <klingt.net@gmail.com>
2020-12-23 10:16:27
Truncate user and group ids for 64 bit Linux systems (#7466)
* Truncate user and group ids Calls to `getuid`, `getgid` and their `eid` variants fail to compile on 64bit Linux systems because the return value of the syscall is of `usize` and needs to be truncated to fit the size of `uid_t` that is 32 bit. Thanks to @FireFox317 for figuring this out in Zig's Discord channel! * Add a regression test for user and group ids * Replace @truncate with @intCast This should be safe because `uid_t` will be 32-bit. * Add missing import for getauxval * Add missing package names * Revert "Add missing import for getauxval" This reverts commit 38f93dc89effdf657f2b81a56b96527ce4083f52. * Skip user and group test if builtin.link_libc
1 parent 4420dab
Changed files (2)
lib
std
lib/std/os/linux/test.zig
@@ -9,6 +9,7 @@ const linux = std.os.linux;
 const mem = std.mem;
 const elf = std.elf;
 const expect = std.testing.expect;
+const expectEqual = std.testing.expectEqual;
 const fs = std.fs;
 
 test "fallocate" {
@@ -99,3 +100,11 @@ test "statx" {
     expect(@bitCast(u64, @as(i64, stat_buf.blksize)) == statx_buf.blksize);
     expect(@bitCast(u64, @as(i64, stat_buf.blocks)) == statx_buf.blocks);
 }
+
+test "user and group ids" {
+    if (builtin.link_libc) return error.SkipZigTest;
+    expectEqual(linux.getauxval(elf.AT_UID), linux.getuid());
+    expectEqual(linux.getauxval(elf.AT_GID), linux.getgid());
+    expectEqual(linux.getauxval(elf.AT_EUID), linux.geteuid());
+    expectEqual(linux.getauxval(elf.AT_EGID), linux.getegid());
+}
lib/std/os/linux.zig
@@ -745,33 +745,33 @@ pub fn setregid(rgid: gid_t, egid: gid_t) usize {
 
 pub fn getuid() uid_t {
     if (@hasField(SYS, "getuid32")) {
-        return @as(uid_t, syscall0(.getuid32));
+        return @intCast(uid_t, syscall0(.getuid32));
     } else {
-        return @as(uid_t, syscall0(.getuid));
+        return @intCast(uid_t, syscall0(.getuid));
     }
 }
 
 pub fn getgid() gid_t {
     if (@hasField(SYS, "getgid32")) {
-        return @as(gid_t, syscall0(.getgid32));
+        return @intCast(gid_t, syscall0(.getgid32));
     } else {
-        return @as(gid_t, syscall0(.getgid));
+        return @intCast(gid_t, syscall0(.getgid));
     }
 }
 
 pub fn geteuid() uid_t {
     if (@hasField(SYS, "geteuid32")) {
-        return @as(uid_t, syscall0(.geteuid32));
+        return @intCast(uid_t, syscall0(.geteuid32));
     } else {
-        return @as(uid_t, syscall0(.geteuid));
+        return @intCast(uid_t, syscall0(.geteuid));
     }
 }
 
 pub fn getegid() gid_t {
     if (@hasField(SYS, "getegid32")) {
-        return @as(gid_t, syscall0(.getegid32));
+        return @intCast(gid_t, syscall0(.getegid32));
     } else {
-        return @as(gid_t, syscall0(.getegid));
+        return @intCast(gid_t, syscall0(.getegid));
     }
 }