authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-05-20 16:53:24+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-05-20 16:53:24+02:00
logb09936d72822e8bb7732f68c6ead369b83c39742
tree9dc2eaa0fd82e58ec83c58c6bcf5c7bc5db1659b
parent9910bfa6d887cd28dba3ac99ac0f0acf8d6e5056
parentec9a44b2a59a9061e1979be5268dd657cd5402fd
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #8842 from LemonBoy/thinko

Some TLCSPRNG fixes

1 files changed, 17 insertions(+), 14 deletions(-)

lib/std/crypto/tlcsprng.zig+17-14
...@@ -48,6 +48,16 @@ const Context = struct {...@@ -48,6 +48,16 @@ const Context = struct {
48 gimli: std.crypto.core.Gimli,48 gimli: std.crypto.core.Gimli,
49};49};
5050
51var install_atfork_handler = std.once(struct {
52 // Install the global handler only once.
53 // The same handler is shared among threads and is inherinted by fork()-ed
54 // processes.
55 fn do() void {
56 const r = std.c.pthread_atfork(null, null, childAtForkHandler);
57 std.debug.assert(r == 0);
58 }
59}.do);
60
51threadlocal var wipe_mem: []align(mem.page_size) u8 = &[_]u8{};61threadlocal var wipe_mem: []align(mem.page_size) u8 = &[_]u8{};
5262
53fn tlsCsprngFill(_: *const std.rand.Random, buffer: []u8) void {63fn tlsCsprngFill(_: *const std.rand.Random, buffer: []u8) void {
...@@ -107,13 +117,9 @@ fn tlsCsprngFill(_: *const std.rand.Random, buffer: []u8) void {...@@ -107,13 +117,9 @@ fn tlsCsprngFill(_: *const std.rand.Random, buffer: []u8) void {
107 break :wof;117 break :wof;
108 } else |_| {}118 } else |_| {}
109119
110 os.madvise(120 if (os.madvise(wipe_mem.ptr, wipe_mem.len, os.MADV_WIPEONFORK)) |_| {
111 wipe_mem.ptr,
112 wipe_mem.len,
113 os.MADV_WIPEONFORK,
114 ) catch {
115 return initAndFill(buffer);121 return initAndFill(buffer);
116 };122 } else |_| {}
117 }123 }
118124
119 if (std.Thread.use_pthreads) {125 if (std.Thread.use_pthreads) {
...@@ -139,17 +145,14 @@ fn tlsCsprngFill(_: *const std.rand.Random, buffer: []u8) void {...@@ -139,17 +145,14 @@ fn tlsCsprngFill(_: *const std.rand.Random, buffer: []u8) void {
139}145}
140146
141fn setupPthreadAtforkAndFill(buffer: []u8) void {147fn setupPthreadAtforkAndFill(buffer: []u8) void {
142 const failed = std.c.pthread_atfork(null, null, childAtForkHandler) != 0;148 install_atfork_handler.call();
143 if (failed) {149 return initAndFill(buffer);
144 const ctx = @ptrCast(*Context, wipe_mem.ptr);
145 ctx.init_state = .failed;
146 return fillWithOsEntropy(buffer);
147 } else {
148 return initAndFill(buffer);
149 }
150}150}
151151
152fn childAtForkHandler() callconv(.C) void {152fn childAtForkHandler() callconv(.C) void {
153 // The atfork handler is global, this function may be called after
154 // fork()-ing threads that never initialized the CSPRNG context.
155 if (wipe_mem.len == 0) return;
153 std.crypto.utils.secureZero(u8, wipe_mem);156 std.crypto.utils.secureZero(u8, wipe_mem);
154}157}
155158