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 {
4848 gimli: std.crypto.core.Gimli,
4949};
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
5161threadlocal var wipe_mem: []align(mem.page_size) u8 = &[_]u8{};
5262
5363fn tlsCsprngFill(_: *const std.rand.Random, buffer: []u8) void {
......@@ -107,13 +117,9 @@ fn tlsCsprngFill(_: *const std.rand.Random, buffer: []u8) void {
107117 break :wof;
108118 } else |_| {}
109119
110 os.madvise(
111 wipe_mem.ptr,
112 wipe_mem.len,
113 os.MADV_WIPEONFORK,
114 ) catch {
120 if (os.madvise(wipe_mem.ptr, wipe_mem.len, os.MADV_WIPEONFORK)) |_| {
115121 return initAndFill(buffer);
116 };
122 } else |_| {}
117123 }
118124
119125 if (std.Thread.use_pthreads) {
......@@ -139,17 +145,14 @@ fn tlsCsprngFill(_: *const std.rand.Random, buffer: []u8) void {
139145}
140146
141147fn setupPthreadAtforkAndFill(buffer: []u8) void {
142 const failed = std.c.pthread_atfork(null, null, childAtForkHandler) != 0;
143 if (failed) {
144 const ctx = @ptrCast(*Context, wipe_mem.ptr);
145 ctx.init_state = .failed;
146 return fillWithOsEntropy(buffer);
147 } else {
148 return initAndFill(buffer);
149 }
148 install_atfork_handler.call();
149 return initAndFill(buffer);
150150}
151151
152152fn 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;
153156 std.crypto.utils.secureZero(u8, wipe_mem);
154157}
155158