From 0237baee923043cfd4ad8f2fda50526df4ffe4a4 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Wed, 26 Feb 2025 23:34:50 -0800 Subject: [PATCH] Zero out sensitive memory before freeing (#17750) --- src/bun.js/api/BunObject.zig | 8 +++++--- src/bun.js/api/server.zig | 8 ++++---- src/bun.zig | 9 +++++++++ src/s3/credentials.zig | 12 ++++++------ src/sql/postgres.zig | 4 +++- 5 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/bun.js/api/BunObject.zig b/src/bun.js/api/BunObject.zig index 8e594f6d33..bbdb984316 100644 --- a/src/bun.js/api/BunObject.zig +++ b/src/bun.js/api/BunObject.zig @@ -1971,7 +1971,7 @@ pub const Crypto = struct { pub fn deinit(this: *HashJob) void { this.promise.deinit(); - bun.default_allocator.free(this.password); + bun.freeSensitive(bun.default_allocator, this.password); this.destroy(); } @@ -2184,8 +2184,10 @@ pub const Crypto = struct { pub fn deinit(this: *VerifyJob) void { this.promise.deinit(); - bun.default_allocator.free(this.password); - bun.default_allocator.free(this.prev_hash); + + bun.freeSensitive(bun.default_allocator, this.password); + bun.freeSensitive(bun.default_allocator, this.prev_hash); + this.destroy(); } diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig index 2ccd00366e..6113ccc11d 100644 --- a/src/bun.js/api/server.zig +++ b/src/bun.js/api/server.zig @@ -769,7 +769,7 @@ pub const ServerConfig = struct { if (@field(this, field)) |slice_ptr| { const slice = std.mem.span(slice_ptr); if (slice.len > 0) { - bun.default_allocator.free(slice); + bun.freeSensitive(bun.default_allocator, slice); } @field(this, field) = ""; } @@ -779,7 +779,7 @@ pub const ServerConfig = struct { for (0..this.cert_count) |i| { const slice = std.mem.span(cert[i]); if (slice.len > 0) { - bun.default_allocator.free(slice); + bun.freeSensitive(bun.default_allocator, slice); } } @@ -791,7 +791,7 @@ pub const ServerConfig = struct { for (0..this.key_count) |i| { const slice = std.mem.span(key[i]); if (slice.len > 0) { - bun.default_allocator.free(slice); + bun.freeSensitive(bun.default_allocator, slice); } } @@ -803,7 +803,7 @@ pub const ServerConfig = struct { for (0..this.ca_count) |i| { const slice = std.mem.span(ca[i]); if (slice.len > 0) { - bun.default_allocator.free(slice); + bun.freeSensitive(bun.default_allocator, slice); } } diff --git a/src/bun.zig b/src/bun.zig index d6e52a6a81..948d1997d8 100644 --- a/src/bun.zig +++ b/src/bun.zig @@ -4350,5 +4350,14 @@ pub fn CowSlice(T: type) type { const Allocator = std.mem.Allocator; +/// Memory is typically not decommitted immediately when freed. +/// Sensitive information that's kept in memory can be read in various ways until the OS +/// decommits it or the memory allocator reuses it for a new allocation. +/// So if we're about to free something sensitive, we should zero it out first. +pub fn freeSensitive(allocator: std.mem.Allocator, slice: anytype) void { + @memset(@constCast(slice), 0); + allocator.free(slice); +} + pub const server = @import("./bun.js/api/server.zig"); pub const macho = @import("./macho.zig"); diff --git a/src/s3/credentials.zig b/src/s3/credentials.zig index 7a1159c301..73e7e8f857 100644 --- a/src/s3/credentials.zig +++ b/src/s3/credentials.zig @@ -357,27 +357,27 @@ pub const S3Credentials = struct { pub fn deinit(this: *const @This()) void { if (this.amz_date.len > 0) { - bun.default_allocator.free(this.amz_date); + bun.freeSensitive(bun.default_allocator, this.amz_date); } if (this.session_token.len > 0) { - bun.default_allocator.free(this.session_token); + bun.freeSensitive(bun.default_allocator, this.session_token); } if (this.content_disposition.len > 0) { - bun.default_allocator.free(this.content_disposition); + bun.freeSensitive(bun.default_allocator, this.content_disposition); } if (this.host.len > 0) { - bun.default_allocator.free(this.host); + bun.freeSensitive(bun.default_allocator, this.host); } if (this.authorization.len > 0) { - bun.default_allocator.free(this.authorization); + bun.freeSensitive(bun.default_allocator, this.authorization); } if (this.url.len > 0) { - bun.default_allocator.free(this.url); + bun.freeSensitive(bun.default_allocator, this.url); } } }; diff --git a/src/sql/postgres.zig b/src/sql/postgres.zig index dc37cb9943..d66fe0baf7 100644 --- a/src/sql/postgres.zig +++ b/src/sql/postgres.zig @@ -2122,7 +2122,9 @@ pub const PostgresSQLConnection = struct { this.write_buffer.deinit(bun.default_allocator); this.read_buffer.deinit(bun.default_allocator); this.backend_parameters.deinit(); - bun.default_allocator.free(this.options_buf); + + bun.freeSensitive(bun.default_allocator, this.options_buf); + this.tls_config.deinit(); bun.default_allocator.destroy(this); }