-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsecret_allocator.zig
95 lines (84 loc) · 2.77 KB
/
secret_allocator.zig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
const std = @import("std");
const Allocator = std.mem.Allocator;
const sodium = @cImport({
@cInclude("sodium.h");
});
pub fn SecretAllocator() type {
return struct {
parent_allocator: Allocator,
const Self = @This();
pub fn init(parent_allocator: Allocator) Self {
return Self{
.parent_allocator = parent_allocator,
};
}
pub fn allocator(self: *Self) Allocator {
return .{
.ptr = self,
.vtable = &.{
.alloc = alloc,
.resize = resize,
.free = free,
},
};
}
fn alloc(
ctx: *anyopaque,
len: usize,
log2_ptr_align: u8,
ra: usize,
) ?[*]u8 {
const self: *Self = @ptrCast(@alignCast(ctx));
const result = self.parent_allocator.rawAlloc(len, log2_ptr_align, ra);
if (result) |buf| {
if(len > 0 and 0!=sodium.sodium_mlock(@ptrCast(buf),len)) {
self.parent_allocator.rawFree(buf[0..len], log2_ptr_align, ra);
return null;
}
}
return result;
}
fn resize(
ctx: *anyopaque,
buf: []u8,
log2_buf_align: u8,
new_len: usize,
ra: usize,
) bool {
const self: *Self = @ptrCast(@alignCast(ctx));
if(new_len==0) _=sodium.sodium_munlock(@ptrCast(buf),buf.len);
if (self.parent_allocator.rawResize(buf, log2_buf_align, new_len, ra)) {
if(new_len>buf.len) _=sodium.sodium_mlock(buf.ptr, new_len);
return true;
}
std.debug.assert(new_len > buf.len);
return false;
}
fn free(
ctx: *anyopaque,
buf: []u8,
log2_buf_align: u8,
ra: usize,
) void {
const self: *Self = @ptrCast(@alignCast(ctx));
_ = sodium.sodium_munlock(buf.ptr,buf.len);
self.parent_allocator.rawFree(buf, log2_buf_align, ra);
}
};
}
pub fn secretAllocator(
parent_allocator: Allocator,
) SecretAllocator() {
return SecretAllocator().init(parent_allocator);
}
test "SecretAllocator" {
var allocator_buf: [10]u8 = undefined;
var fixedBufferAllocator = std.mem.validationWrap(std.heap.FixedBufferAllocator.init(&allocator_buf));
var allocator_state = secretAllocator(fixedBufferAllocator.allocator());
const allocator = allocator_state.allocator();
var a = try allocator.alloc(u8, 10);
try std.testing.expect(allocator.resize(a, 5));
a = a[0..5];
try std.testing.expect(!allocator.resize(a, 20));
allocator.free(a);
}