Skip to content

Commit f30ccd9

Browse files
authored
secure memory ops (#248)
* add mir_secure_memory version * add configs
1 parent 301021a commit f30ccd9

File tree

6 files changed

+69
-8
lines changed

6 files changed

+69
-8
lines changed

dub.sdl

+4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ buildType "unittest-release" {
2323
configuration "default" {
2424
}
2525

26+
configuration "secure" {
27+
versions "mir_secure_memory"
28+
}
29+
2630
configuration "dip1008" {
2731
dflags "-preview=dip1008"
2832
}

meson.build

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ this_dep = declare_dependency(
102102
dependencies: required_deps,
103103
)
104104

105-
test_versions = ['mir_test', 'NOGCEXP']
105+
test_versions = ['mir_test', 'NOGCEXP', 'mir_secure_memory']
106106

107107
if has_cpp_headers
108108
install_subdir('include/',

source/mir/appender.d

+23-2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,15 @@ struct ScopedBuffer(T, size_t bytes = 4096)
5353
else
5454
{
5555
auto newLen = _currentLength << 1;
56-
_buffer = (cast(T*)malloc(T.sizeof * newLen))[0 .. newLen];
56+
if (auto p = malloc(T.sizeof * newLen))
57+
{
58+
_buffer = (cast(T*)p)[0 .. newLen];
59+
}
60+
else assert(0);
61+
version (mir_secure_memory)
62+
{
63+
(cast(ubyte[])_buffer)[] = 0;
64+
}
5765
memcpy(cast(void*)_buffer.ptr, _scopeBuffer.ptr, T.sizeof * (_currentLength - n));
5866
}
5967
}
@@ -62,6 +70,10 @@ struct ScopedBuffer(T, size_t bytes = 4096)
6270
{
6371
auto newLen = _currentLength << 1;
6472
_buffer = (cast(T*)realloc(cast(void*)_buffer.ptr, T.sizeof * newLen))[0 .. newLen];
73+
version (mir_secure_memory)
74+
{
75+
(cast(ubyte[])_buffer[_currentLength .. $])[] = 0;
76+
}
6577
}
6678
return _buffer[0 .. _currentLength];
6779
}
@@ -78,7 +90,16 @@ struct ScopedBuffer(T, size_t bytes = 4096)
7890
import mir.internal.memory: malloc;
7991
if (_buffer.ptr)
8092
{
81-
auto buffer = (cast(T*)malloc(T.sizeof * _buffer.length))[0 .. _buffer.length];
93+
typeof(_buffer) buffer;
94+
if (auto p = malloc(T.sizeof * _buffer.length))
95+
{
96+
buffer = (cast(T*)p)[0 .. T.sizeof * _buffer.length];
97+
}
98+
else assert(0);
99+
version (mir_secure_memory)
100+
{
101+
(cast(ubyte[])buffer)[] = 0;
102+
}
82103
buffer[0 .. _currentLength] = _buffer[0 .. _currentLength];
83104
_buffer = buffer;
84105
}

source/mir/ndslice/allocation.d

+27-1
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,10 @@ auto uninitSlice(T, size_t N)(size_t[N] lengths...)
496496
immutable len = lengths.lengthsProduct;
497497
import std.array : uninitializedArray;
498498
auto arr = uninitializedArray!(T[])(len);
499+
version (mir_secure_memory)
500+
{()@trusted{
501+
(cast(ubyte[])arr)[] = 0;
502+
}();}
499503
return arr.sliced(lengths);
500504
}
501505

@@ -646,6 +650,10 @@ makeUninitSlice(T, Allocator, size_t N)(auto ref Allocator alloc, size_t[N] leng
646650
auto mem = alloc.allocate(len * T.sizeof);
647651
if (mem.length == 0) assert(0);
648652
auto array = () @trusted { return cast(T[]) mem; }();
653+
version (mir_secure_memory)
654+
{() @trusted {
655+
(cast(ubyte[])array)[] = 0;
656+
}();}
649657
return array.sliced(lengths);
650658
}
651659
else
@@ -856,7 +864,13 @@ Slice!(T*, N) stdcUninitSlice(T, size_t N)(size_t[N] lengths...)
856864
{
857865
import core.stdc.stdlib: malloc;
858866
immutable len = lengths.lengthsProduct;
859-
auto ptr = len ? cast(T*) malloc(len * T.sizeof) : null;
867+
auto p = malloc(len * T.sizeof);
868+
if (p is null) assert(0);
869+
version (mir_secure_memory)
870+
{
871+
(cast(ubyte*)p)[0 .. len * T.sizeof] = 0;
872+
}
873+
auto ptr = len ? cast(T*) p : null;
860874
return ptr.sliced(lengths);
861875
}
862876

@@ -892,6 +906,10 @@ See_also:
892906
void stdcFreeSlice(T, size_t N)(Slice!(T*, N) slice)
893907
{
894908
import core.stdc.stdlib: free;
909+
version (mir_secure_memory)
910+
{
911+
(cast(ubyte[])slice.field)[] = 0;
912+
}
895913
slice._iterator.free;
896914
}
897915

@@ -926,6 +944,10 @@ auto stdcUninitAlignedSlice(T, size_t N)(size_t[N] lengths, uint alignment) @sys
926944
immutable len = lengths.lengthsProduct;
927945
import mir.internal.memory: alignedAllocate;
928946
auto arr = (cast(T*)alignedAllocate(len * T.sizeof, alignment))[0 .. len];
947+
version (mir_secure_memory)
948+
{
949+
(cast(ubyte[])arr)[] = 0;
950+
}
929951
return arr.sliced(lengths);
930952
}
931953

@@ -951,5 +973,9 @@ See_also:
951973
void stdcFreeAlignedSlice(T, size_t N)(Slice!(T*, N) slice)
952974
{
953975
import mir.internal.memory: alignedFree;
976+
version (mir_secure_memory)
977+
{
978+
(cast(ubyte[])slice.field)[] = 0;
979+
}
954980
slice._iterator.alignedFree;
955981
}

source/mir/rc/context.d

+13-1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,12 @@ void mir_rc_delete(ref mir_rc_context context)
8787
}
8888
}
8989
}
90+
if (context.counter)
91+
assert(0);
92+
version (mir_secure_memory)
93+
{
94+
(cast(ubyte*)(&context + 1))[0 .. context.length * context.typeInfo.size] = 0;
95+
}
9096
context.deallocator(&context);
9197
}
9298

@@ -106,8 +112,14 @@ mir_rc_context* mir_rc_create(
106112

107113
assert(length);
108114
auto size = length * typeInfo.size;
109-
if (auto context = cast(mir_rc_context*)malloc(mir_rc_context.sizeof + size))
115+
auto fullSize = mir_rc_context.sizeof + size;
116+
if (auto p = malloc(fullSize))
110117
{
118+
version (mir_secure_memory)
119+
{
120+
(cast(ubyte*)p)[0 .. fullSize] = 0;
121+
}
122+
auto context = cast(mir_rc_context*)p;
111123
context.deallocator = &free;
112124
context.typeInfo = &typeInfo;
113125
context.counter = deallocate;

source/mir/type_info.d

+1-3
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ struct mir_type_info
2727
int size;
2828
}
2929

30-
/++
31-
Convinience function for integration with .NET.
32-
+/
30+
deprecated
3331
export extern(C) void mir_type_info_init(ref mir_type_info ti, typeof(mir_type_info.init.destructor) destructor, int size)
3432
@safe pure nothrow @nogc
3533
{

0 commit comments

Comments
 (0)