authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-06 17:29:39-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-07 11:03:37-08:00
log8e1850e277c3112eda44b8bb3de95ef1791eccfa
treeab876b5d74d1cd9040a41c187336e5a17e758943
parent61cb5e4af92cd96247c59974cb3d59e5900926c1

std.Io.Threaded: tweak logic for use_dev_urandom


1 files changed, 40 insertions(+), 37 deletions(-)

lib/std/Io/Threaded.zig+40-37
...@@ -1744,18 +1744,17 @@ const statx_use_c = std.c.versionCheck(if (builtin.abi.isAndroid())...@@ -1744,18 +1744,17 @@ const statx_use_c = std.c.versionCheck(if (builtin.abi.isAndroid())
1744else1744else
1745 .{ .major = 2, .minor = 28, .patch = 0 });1745 .{ .major = 2, .minor = 28, .patch = 0 });
17461746
1747const getrandom_use_libc = @TypeOf(posix.system.getrandom) != void and (native_os != .linux or1747const use_libc_getrandom = std.c.versionCheck(if (builtin.abi.isAndroid()) .{
1748 std.c.versionCheck(if (builtin.abi.isAndroid()) .{1748 .major = 28,
1749 .major = 28,1749 .minor = 0,
1750 .minor = 0,1750 .patch = 0,
1751 .patch = 0,1751} else .{
1752 } else .{1752 .major = 2,
1753 .major = 2,1753 .minor = 25,
1754 .minor = 25,1754 .patch = 0,
1755 .patch = 0,1755});
1756 }));
17571756
1758const use_dev_urandom = !getrandom_use_libc and native_os == .linux;1757const use_dev_urandom = @TypeOf(posix.system.getrandom) == void and native_os == .linux;
17591758
1760fn async(1759fn async(
1761 userdata: ?*anyopaque,1760 userdata: ?*anyopaque,
...@@ -15149,9 +15148,9 @@ fn fallbackSeedWasi(seed: *[Csprng.seed_len]u8) void {...@@ -15149,9 +15148,9 @@ fn fallbackSeedWasi(seed: *[Csprng.seed_len]u8) void {
1514915148
15150fn randomSecure(userdata: ?*anyopaque, buffer: []u8) Io.RandomSecureError!void {15149fn randomSecure(userdata: ?*anyopaque, buffer: []u8) Io.RandomSecureError!void {
15151 const t: *Threaded = @ptrCast(@alignCast(userdata));15150 const t: *Threaded = @ptrCast(@alignCast(userdata));
15151 if (buffer.len == 0) return;
1515215152
15153 if (is_windows) {15153 if (is_windows) {
15154 if (buffer.len == 0) return;
15155 // ProcessPrng from bcryptprimitives.dll has the following properties:15154 // ProcessPrng from bcryptprimitives.dll has the following properties:
15156 // * introduces a dependency on bcryptprimitives.dll, which apparently15155 // * introduces a dependency on bcryptprimitives.dll, which apparently
15157 // runs a test suite every time it is loaded15156 // runs a test suite every time it is loaded
...@@ -15213,7 +15212,7 @@ fn randomSecure(userdata: ?*anyopaque, buffer: []u8) Io.RandomSecureError!void {...@@ -15213,7 +15212,7 @@ fn randomSecure(userdata: ?*anyopaque, buffer: []u8) Io.RandomSecureError!void {
15213 }15212 }
1521415213
15215 if (@TypeOf(posix.system.getrandom) != void) {15214 if (@TypeOf(posix.system.getrandom) != void) {
15216 const getrandom = if (getrandom_use_libc) std.c.getrandom else std.os.linux.getrandom;15215 const getrandom = if (use_libc_getrandom) std.c.getrandom else std.os.linux.getrandom;
15217 var i: usize = 0;15216 var i: usize = 0;
15218 const syscall: Syscall = try .start();15217 const syscall: Syscall = try .start();
15219 while (i < buffer.len) {15218 while (i < buffer.len) {
...@@ -15244,34 +15243,38 @@ fn randomSecure(userdata: ?*anyopaque, buffer: []u8) Io.RandomSecureError!void {...@@ -15244,34 +15243,38 @@ fn randomSecure(userdata: ?*anyopaque, buffer: []u8) Io.RandomSecureError!void {
15244 }15243 }
15245 }15244 }
1524615245
15247 if (buffer.len == 0) return;15246 if (native_os == .linux) {
15248 const urandom_fd = try getRandomFd(t);15247 comptime assert(use_dev_urandom);
15248 const urandom_fd = try getRandomFd(t);
1524915249
15250 var i: usize = 0;15250 var i: usize = 0;
15251 while (buffer.len - i != 0) {15251 while (buffer.len - i != 0) {
15252 const syscall: Syscall = try .start();15252 const syscall: Syscall = try .start();
15253 const rc = posix.system.read(urandom_fd, buffer[i..].ptr, buffer.len - i);15253 const rc = posix.system.read(urandom_fd, buffer[i..].ptr, buffer.len - i);
15254 switch (posix.errno(rc)) {15254 switch (posix.errno(rc)) {
15255 .SUCCESS => {15255 .SUCCESS => {
15256 syscall.finish();15256 syscall.finish();
15257 const n: usize = @intCast(rc);15257 const n: usize = @intCast(rc);
15258 if (n == 0) {15258 if (n == 0) {
15259 if (buffer.len - i != 0) {15259 if (buffer.len - i != 0) {
15260 return error.EntropyUnavailable;15260 return error.EntropyUnavailable;
15261 } else {15261 } else {
15262 return;15262 return;
15263 }
15263 }15264 }
15264 }15265 i += n;
15265 i += n;15266 continue;
15266 continue;15267 },
15267 },15268 .INTR => {
15268 .INTR => {15269 try syscall.checkCancel();
15269 try syscall.checkCancel();15270 continue;
15270 continue;15271 },
15271 },15272 else => return syscall.fail(error.EntropyUnavailable),
15272 else => return syscall.fail(error.EntropyUnavailable),15273 }
15273 }15274 }
15274 }15275 }
15276
15277 return error.EntropyUnavailable;
15275}15278}
1527615279
15277fn getRandomFd(t: *Threaded) Io.RandomSecureError!posix.fd_t {15280fn getRandomFd(t: *Threaded) Io.RandomSecureError!posix.fd_t {