From 013efaf13987acfa6b41d40f07900c1ea77f5bda Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 17 Dec 2020 20:03:41 -0700 Subject: std: introduce a thread-local CSPRNG for general use std.crypto.random * cross platform, even freestanding * can't fail. on initialization for some systems requires calling os.getrandom(), in which case there are rare but theoretically possible errors. The code panics in these cases, however the application may choose to override the default seed function and then handle the failure another way. * thread-safe * supports the full Random interface * cryptographically secure * no syscall required to initialize on Linux (AT_RANDOM) * calls arc4random on systems that support it `std.crypto.randomBytes` is removed in favor of `std.crypto.random.bytes`. I moved some of the Random implementations into their own files in the interest of organization. stage2 no longer requires passing a RNG; instead it uses this API. Closes #6704 --- src/Compilation.zig | 7 +------ src/glibc.zig | 1 - src/libcxx.zig | 2 -- src/libunwind.zig | 1 - src/main.zig | 15 --------------- src/musl.zig | 1 - src/test.zig | 11 +---------- 7 files changed, 2 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/Compilation.zig b/src/Compilation.zig index 356a1cedf6..5e95575642 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -74,7 +74,6 @@ zig_lib_directory: Directory, local_cache_directory: Directory, global_cache_directory: Directory, libc_include_dir_list: []const []const u8, -rand: *std.rand.Random, /// Populated when we build the libc++ static library. A Job to build this is placed in the queue /// and resolved before calling linker.flush(). @@ -331,7 +330,6 @@ pub const InitOptions = struct { root_name: []const u8, root_pkg: ?*Package, output_mode: std.builtin.OutputMode, - rand: *std.rand.Random, dynamic_linker: ?[]const u8 = null, /// `null` means to not emit a binary file. emit_bin: ?EmitLoc, @@ -981,7 +979,6 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .self_exe_path = options.self_exe_path, .libc_include_dir_list = libc_dirs.libc_include_dir_list, .sanitize_c = sanitize_c, - .rand = options.rand, .clang_passthrough_mode = options.clang_passthrough_mode, .clang_preprocessor_mode = options.clang_preprocessor_mode, .verbose_cc = options.verbose_cc, @@ -1909,7 +1906,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_comp_progress_node: * pub fn tmpFilePath(comp: *Compilation, arena: *Allocator, suffix: []const u8) error{OutOfMemory}![]const u8 { const s = std.fs.path.sep_str; - const rand_int = comp.rand.int(u64); + const rand_int = std.crypto.random.int(u64); if (comp.local_cache_directory.path) |p| { return std.fmt.allocPrint(arena, "{}" ++ s ++ "tmp" ++ s ++ "{x}-{s}", .{ p, rand_int, suffix }); } else { @@ -2778,7 +2775,6 @@ fn buildOutputFromZig( .root_name = root_name, .root_pkg = &root_pkg, .output_mode = fixed_output_mode, - .rand = comp.rand, .libc_installation = comp.bin_file.options.libc_installation, .emit_bin = emit_bin, .optimize_mode = optimize_mode, @@ -3152,7 +3148,6 @@ pub fn build_crt_file( .root_name = root_name, .root_pkg = null, .output_mode = output_mode, - .rand = comp.rand, .libc_installation = comp.bin_file.options.libc_installation, .emit_bin = emit_bin, .optimize_mode = comp.bin_file.options.optimize_mode, diff --git a/src/glibc.zig b/src/glibc.zig index 901054176e..15c9d743f9 100644 --- a/src/glibc.zig +++ b/src/glibc.zig @@ -936,7 +936,6 @@ fn buildSharedLib( .root_pkg = null, .output_mode = .Lib, .link_mode = .Dynamic, - .rand = comp.rand, .libc_installation = comp.bin_file.options.libc_installation, .emit_bin = emit_bin, .optimize_mode = comp.bin_file.options.optimize_mode, diff --git a/src/libcxx.zig b/src/libcxx.zig index 39ec776659..8de45a49b2 100644 --- a/src/libcxx.zig +++ b/src/libcxx.zig @@ -162,7 +162,6 @@ pub fn buildLibCXX(comp: *Compilation) !void { .root_name = root_name, .root_pkg = null, .output_mode = output_mode, - .rand = comp.rand, .libc_installation = comp.bin_file.options.libc_installation, .emit_bin = emit_bin, .optimize_mode = comp.bin_file.options.optimize_mode, @@ -281,7 +280,6 @@ pub fn buildLibCXXABI(comp: *Compilation) !void { .root_name = root_name, .root_pkg = null, .output_mode = output_mode, - .rand = comp.rand, .libc_installation = comp.bin_file.options.libc_installation, .emit_bin = emit_bin, .optimize_mode = comp.bin_file.options.optimize_mode, diff --git a/src/libunwind.zig b/src/libunwind.zig index ec8fe990e9..9822016ae1 100644 --- a/src/libunwind.zig +++ b/src/libunwind.zig @@ -95,7 +95,6 @@ pub fn buildStaticLib(comp: *Compilation) !void { .root_name = root_name, .root_pkg = null, .output_mode = output_mode, - .rand = comp.rand, .libc_installation = comp.bin_file.options.libc_installation, .emit_bin = emit_bin, .optimize_mode = comp.bin_file.options.optimize_mode, diff --git a/src/main.zig b/src/main.zig index 0222d499fa..c54cc6515b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1632,13 +1632,6 @@ fn buildOutputType( }; defer zig_lib_directory.handle.close(); - const random_seed = blk: { - var random_seed: u64 = undefined; - try std.crypto.randomBytes(mem.asBytes(&random_seed)); - break :blk random_seed; - }; - var default_prng = std.rand.DefaultPrng.init(random_seed); - var libc_installation: ?LibCInstallation = null; defer if (libc_installation) |*l| l.deinit(gpa); @@ -1754,7 +1747,6 @@ fn buildOutputType( .single_threaded = single_threaded, .function_sections = function_sections, .self_exe_path = self_exe_path, - .rand = &default_prng.random, .clang_passthrough_mode = arg_mode != .build, .clang_preprocessor_mode = clang_preprocessor_mode, .version = optional_version, @@ -2420,12 +2412,6 @@ pub fn cmdBuild(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v .directory = null, // Use the local zig-cache. .basename = exe_basename, }; - const random_seed = blk: { - var random_seed: u64 = undefined; - try std.crypto.randomBytes(mem.asBytes(&random_seed)); - break :blk random_seed; - }; - var default_prng = std.rand.DefaultPrng.init(random_seed); const comp = Compilation.create(gpa, .{ .zig_lib_directory = zig_lib_directory, .local_cache_directory = local_cache_directory, @@ -2441,7 +2427,6 @@ pub fn cmdBuild(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v .emit_h = null, .optimize_mode = .Debug, .self_exe_path = self_exe_path, - .rand = &default_prng.random, }) catch |err| { fatal("unable to create compilation: {}", .{@errorName(err)}); }; diff --git a/src/musl.zig b/src/musl.zig index ac39eb7d74..1a30a6e2b9 100644 --- a/src/musl.zig +++ b/src/musl.zig @@ -200,7 +200,6 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void { .root_pkg = null, .output_mode = .Lib, .link_mode = .Dynamic, - .rand = comp.rand, .libc_installation = comp.bin_file.options.libc_installation, .emit_bin = Compilation.EmitLoc{ .directory = null, .basename = "libc.so" }, .optimize_mode = comp.bin_file.options.optimize_mode, diff --git a/src/test.zig b/src/test.zig index 251edc2d34..e0497a8cd5 100644 --- a/src/test.zig +++ b/src/test.zig @@ -467,13 +467,6 @@ pub const TestContext = struct { defer zig_lib_directory.handle.close(); defer std.testing.allocator.free(zig_lib_directory.path.?); - const random_seed = blk: { - var random_seed: u64 = undefined; - try std.crypto.randomBytes(std.mem.asBytes(&random_seed)); - break :blk random_seed; - }; - var default_prng = std.rand.DefaultPrng.init(random_seed); - for (self.cases.items) |case| { if (build_options.skip_non_native and case.target.getCpuArch() != std.Target.current.cpu.arch) continue; @@ -487,7 +480,7 @@ pub const TestContext = struct { progress.initial_delay_ns = 0; progress.refresh_rate_ns = 0; - try self.runOneCase(std.testing.allocator, &prg_node, case, zig_lib_directory, &default_prng.random); + try self.runOneCase(std.testing.allocator, &prg_node, case, zig_lib_directory); } } @@ -497,7 +490,6 @@ pub const TestContext = struct { root_node: *std.Progress.Node, case: Case, zig_lib_directory: Compilation.Directory, - rand: *std.rand.Random, ) !void { const target_info = try std.zig.system.NativeTargetInfo.detect(allocator, case.target); const target = target_info.target; @@ -547,7 +539,6 @@ pub const TestContext = struct { .local_cache_directory = zig_cache_directory, .global_cache_directory = zig_cache_directory, .zig_lib_directory = zig_lib_directory, - .rand = rand, .root_name = "test_case", .target = target, // TODO: support tests for object file building, and library builds -- cgit v1.2.3