diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-12-18 15:38:38 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-12-18 15:54:01 -0700 |
| commit | 53987c932c9d62cc9cdae3d523fb62756ce83ca9 (patch) | |
| tree | 280817d390ef900cf590c40f47cca4230b354b0e /lib/std/start.zig | |
| parent | 2b8dcc76eba92ad44bd88756218de8d2bd8a1c10 (diff) | |
| download | zig-53987c932c9d62cc9cdae3d523fb62756ce83ca9.tar.gz zig-53987c932c9d62cc9cdae3d523fb62756ce83ca9.zip | |
std.crypto.random: introduce fork safety
Everybody gets what they want!
* AT_RANDOM is completely ignored.
* On Linux, MADV_WIPEONFORK is used to provide fork safety.
* On pthread systems, `pthread_atfork` is used to provide fork safety.
* For systems that do not have the capability to provide fork safety,
the implementation falls back to calling getrandom() every time.
* If madvise is unavailable or returns an error, or pthread_atfork
fails for whatever reason, it falls back to calling getrandom() every
time.
* Applications may choose to opt-out of fork safety.
* Applications may choose to opt-in to unconditionally calling
getrandom() for every call to std.crypto.random.fillFn.
* Added `std.meta.globalOption`.
* Added `std.os.madvise` and related bits.
* Bumped up the size of the main thread TLS buffer. See the comment
there for justification.
* Simpler hot path in TLS initialization.
Diffstat (limited to 'lib/std/start.zig')
| -rw-r--r-- | lib/std/start.zig | 26 |
1 files changed, 0 insertions, 26 deletions
diff --git a/lib/std/start.zig b/lib/std/start.zig index 8d5eda6105..01fe43ca35 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -216,12 +216,6 @@ fn posixCallMainAndExit() noreturn { std.os.linux.tls.initStaticTLS(); } - if (!@hasDecl(root, "use_AT_RANDOM_auxval") or root.use_AT_RANDOM_auxval) { - // Initialize the per-thread CSPRNG since Linux gave us the handy-dandy - // AT_RANDOM. This depends on the TLS initialization above. - initCryptoSeedFromAuxVal(std.os.linux.getauxval(std.elf.AT_RANDOM)); - } - // TODO This is disabled because what should we do when linking libc and this code // does not execute? And also it's causing a test failure in stack traces in release modes. @@ -257,32 +251,12 @@ fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 { } fn main(c_argc: i32, c_argv: [*][*:0]u8, c_envp: [*:null]?[*:0]u8) callconv(.C) i32 { - // By default, we do not attempt to initialize tlcsprng from AT_RANDOM here because - // libc owns the start code, not us, and therefore libc owns the random bytes - // from AT_RANDOM. - if (builtin.os.tag == .linux and - @hasDecl(root, "use_AT_RANDOM_auxval") and - root.use_AT_RANDOM_auxval) - { - initCryptoSeedFromAuxVal(std.c.getauxval(std.elf.AT_RANDOM)); - } var env_count: usize = 0; while (c_envp[env_count] != null) : (env_count += 1) {} const envp = @ptrCast([*][*:0]u8, c_envp)[0..env_count]; return @call(.{ .modifier = .always_inline }, callMainWithArgs, .{ @intCast(usize, c_argc), c_argv, envp }); } -fn initCryptoSeedFromAuxVal(addr: usize) void { - if (addr == 0) return; - // "The address of sixteen bytes containing a random value." - const ptr = @intToPtr(*[16]u8, addr); - tlcsprng.init(ptr.*); - // Clear AT_RANDOM after we use it, otherwise our secure - // seed is sitting in memory ready for some other code in the - // program to reuse, and hence break our security. - std.crypto.utils.secureZero(u8, ptr); -} - // General error message for a malformed return type const bad_main_ret = "expected return type of main to be 'void', '!void', 'noreturn', 'u8', or '!u8'"; |
