Zaman
Zaman (زمان in Persian) is a memory safety tool for Zig that tries to prevent use-after-free and ifetime confusion at compile time by encoding arena lifetimes directly into pointer types.
Why does this exist?
I have several die-hard Rustacean friends who were constantly bragging about their nice memory-safety features, so I decided to end the discussion by implementing their beloved lifetimes using Zig’s comptime
Why should you care?
- Manual memory management in Zig is manageable - but sometimes you need stronger guarantees
- There are safe usage patterns that are not implementable in Rust
- Usually the attack surface is limited compared to the entire codebase, so you don’t need to bear the burden of Rust’s rules for its entirety
- For long-running applications, Zaman might reduce memory fragmentation and improve allocation throughput at the cost of slightly higher memory consumption, compared to many allocation strategies including Rust’s (you can optimize this balance as you wish)
- This is a benchmark of what Zig’s
comptimeis capable of and you might apply these ideas to your own use-cases
Usage
const La = Lifetime(@src(), .{});
defer La.deinit();
const x = try La.create(i32);
var y = try La.create(i32);
// x and y share the Lifetime La
const Lb = Lifetime(@src(), .{});
defer Lb.deinit();
const z = try Lb.create(i32);
y = z; // compilation error!
// z has the Lifetime Lb != La
What about use-after-free?
const La = Lifetime(@src(), .{});
defer La.deinit();
var use_after_free: La.Bound(*u32) = undefined;
{
const Lb = Lifetime(@src(), .{});
defer Lb.deinit();
const x = try Lb.create(u32);
x.set(10);
use_after_free = x;
}
std.debug.print("{}\n", use_after_free.get());
compilation output
src/uaf.zig:14:26: error: expected type 'lifetime.Bounded(*u32,"uaf |zaman> uaf.zig:4:25"[0..24])',
found 'lifetime.Bounded(*u32,"uaf |zaman> uaf.zig:9:29"[0..24])'
use_after_free = x;
^
src/lifetime.zig:84:12: note: struct declared here (2 times)
return struct {
^~~~~~
Supported Zig versions
This package doesn’t use any version specific std/language feature so it could be used in any zig version with zero or minimal modification
masterdirectly supports from zig-0.15.0 to zig-0.16.0