Skip to content

Commit 0ff0dae

Browse files
committed
Unpoison stack on procedure return
1 parent 45d1a62 commit 0ff0dae

File tree

9 files changed

+40
-5
lines changed

9 files changed

+40
-5
lines changed

base/intrinsics/intrinsics.odin

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,3 +368,6 @@ valgrind_client_request :: proc(default: uintptr, request: uintptr, a0, a1, a2,
368368
// Internal compiler use only
369369

370370
__entry_point :: proc() ---
371+
372+
373+
__asan_unpoison_memory_region :: proc "system" (address: rawptr, size: uint) ---

base/runtime/internal.odin

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,3 +1106,12 @@ __read_bits :: proc "contextless" (dst, src: [^]byte, offset: uintptr, size: uin
11061106
dst[j>>3] |= the_bit<<(j&7)
11071107
}
11081108
}
1109+
1110+
@(no_sanitize_address)
1111+
__asan_unpoison_memory_region :: #force_inline proc "contextless" (address: rawptr, size: uint) {
1112+
foreign {
1113+
__asan_unpoison_memory_region :: proc(address: rawptr, size: uint) ---
1114+
}
1115+
__asan_unpoison_memory_region(address, size)
1116+
}
1117+

core/mem/virtual/arena.odin

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ arena_init_buffer :: proc(arena: ^Arena, buffer: []byte) -> (err: Allocator_Erro
8282

8383
arena.kind = .Buffer
8484

85-
// sanitizer.address_poison(buffer[:])
85+
sanitizer.address_poison(buffer[:])
8686

8787
block_base := raw_data(buffer)
8888
block := (^Memory_Block)(block_base)
@@ -182,7 +182,7 @@ arena_static_reset_to :: proc(arena: ^Arena, pos: uint, loc := #caller_location)
182182
mem.zero_slice(arena.curr_block.base[arena.curr_block.used:][:prev_pos-pos])
183183
}
184184
arena.total_used = arena.curr_block.used
185-
// sanitizer.address_poison(arena.curr_block.base[:arena.curr_block.committed])
185+
sanitizer.address_poison(arena.curr_block.base[:arena.curr_block.committed])
186186
return true
187187
} else if pos == 0 {
188188
arena.total_used = 0
@@ -349,7 +349,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
349349
if size < old_size {
350350
// shrink data in-place
351351
data = old_data[:size]
352-
// sanitizer.address_poison(old_data[size:old_size])
352+
sanitizer.address_poison(old_data[size:old_size])
353353
return
354354
}
355355

@@ -374,7 +374,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
374374
return
375375
}
376376
copy(new_memory, old_data[:old_size])
377-
// sanitizer.address_poison(old_data[:old_size])
377+
sanitizer.address_poison(old_data[:old_size])
378378
return new_memory, nil
379379
case .Query_Features:
380380
set := (^mem.Allocator_Mode_Set)(old_memory)

core/testing/runner.odin

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import "core:thread"
2929
import "core:time"
3030

3131
// Specify how many threads to use when running tests.
32-
TEST_THREADS : int : #config(ODIN_TEST_THREADS, 1)
32+
TEST_THREADS : int : #config(ODIN_TEST_THREADS, 0)
3333
// Track the memory used by each test.
3434
TRACKING_MEMORY : bool : #config(ODIN_TEST_TRACK_MEMORY, true)
3535
// Always report how much memory is used, even when there are no leaks or bad frees.

src/checker_builtin_procs.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,8 @@ BuiltinProc__type_end,
344344

345345
BuiltinProc_valgrind_client_request,
346346

347+
BuiltinProc_asan_unpoison_memory_region,
348+
347349
BuiltinProc_COUNT,
348350
};
349351
gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
@@ -687,4 +689,6 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
687689
{STR_LIT("wasm_memory_atomic_notify32"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
688690

689691
{STR_LIT("valgrind_client_request"), 7, false, Expr_Expr, BuiltinProcPkg_intrinsics},
692+
693+
{STR_LIT("__asan_unpoison_memory_region"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
690694
};

src/llvm_backend.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,8 @@ struct lbProcedure {
383383
PtrMap<Ast *, lbValue> selector_values;
384384
PtrMap<Ast *, lbAddr> selector_addr;
385385
PtrMap<LLVMValueRef, lbTupleFix> tuple_fix_map;
386+
387+
Array<lbValue> locals;
386388
};
387389

388390

src/llvm_backend_general.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3070,6 +3070,10 @@ gb_internal lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e, bool zero
30703070
if (e != nullptr) {
30713071
lb_add_entity(p->module, e, val);
30723072
lb_add_debug_local_variable(p, ptr, type, e->token);
3073+
3074+
if (build_context.sanitizer_flags & SanitizerFlag_Address && !p->entity->Procedure.no_sanitize_address) {
3075+
array_add(&p->locals, val);
3076+
}
30733077
}
30743078

30753079
if (zero_init) {

src/llvm_backend_proc.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i
121121
p->branch_blocks.allocator = a;
122122
p->context_stack.allocator = a;
123123
p->scope_stack.allocator = a;
124+
p->locals.allocator = a;
124125
// map_init(&p->selector_values, 0);
125126
// map_init(&p->selector_addr, 0);
126127
// map_init(&p->tuple_fix_map, 0);
@@ -390,6 +391,7 @@ gb_internal lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name
390391
p->blocks.allocator = a;
391392
p->branch_blocks.allocator = a;
392393
p->context_stack.allocator = a;
394+
p->locals.allocator = a;
393395
map_init(&p->tuple_fix_map, 0);
394396

395397

src/llvm_backend_stmt.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2917,6 +2917,17 @@ gb_internal void lb_emit_defer_stmts(lbProcedure *p, lbDeferExitKind kind, lbBlo
29172917
}
29182918
defer (p->branch_location_pos = prev_token_pos);
29192919

2920+
if (kind == lbDeferExit_Return) {
2921+
for_array(i, p->locals) {
2922+
lbValue local = p->locals[i];
2923+
2924+
auto args = array_make<lbValue>(temporary_allocator(), 2);
2925+
args[0] = lb_emit_conv(p, local, t_rawptr);
2926+
args[1] = lb_const_int(p->module, t_int, type_size_of(local.type->Pointer.elem));
2927+
lb_emit_runtime_call(p, "__asan_unpoison_memory_region", args);
2928+
}
2929+
}
2930+
29202931
isize count = p->defer_stmts.count;
29212932
isize i = count;
29222933
while (i --> 0) {

0 commit comments

Comments
 (0)