aboutsummaryrefslogtreecommitdiff
path: root/content/posts/2026-01-15-using-address-sanitizer-with-clang.md
diff options
context:
space:
mode:
Diffstat (limited to 'content/posts/2026-01-15-using-address-sanitizer-with-clang.md')
-rw-r--r--content/posts/2026-01-15-using-address-sanitizer-with-clang.md124
1 files changed, 124 insertions, 0 deletions
diff --git a/content/posts/2026-01-15-using-address-sanitizer-with-clang.md b/content/posts/2026-01-15-using-address-sanitizer-with-clang.md
new file mode 100644
index 0000000..5ddc149
--- /dev/null
+++ b/content/posts/2026-01-15-using-address-sanitizer-with-clang.md
@@ -0,0 +1,124 @@
1---
2title: Using Address Sanitizer with clang
3url: using-address-sanitizer-with-clang.html
4date: 2026-01-15T16:13:13+02:00
5type: post
6draft: false
7tags: []
8---
9
10## What -fsanitize=address does
11
12- Enables AddressSanitizer (ASan): a compile and link time instrumentation plus
13 runtime library that detects memory errors.
14- Detects: out-of-bounds accesses (heap, stack, globals), use-after-free, some
15 use-after-return, double/invalid free, and (on some platforms) leaks.
16- How it works: instrumented memory accesses are checked against a shadow
17 memory; violations produce an error report with a stack trace and abort the
18 program.
19- Trade-offs: ~2x runtime slowdown (varies), higher memory use, large virtual
20 address space reservation on 64-bit, and requires linking the ASan runtime
21 (not suitable for production builds).
22- Usage: compile and link with `-fsanitize=address` (and typically `-g` and
23 `-O0`). Runtime behavior can be tuned via `ASAN_OPTIONS` and
24 symbolization via llvm-symbolizer.
25
26More about ASan on https://clang.llvm.org/docs/AddressSanitizer.html.
27
28## An example how to use it
29
30```c
31#include <stdlib.h>
32#include <stdio.h>
33#include <string.h>
34
35int main(void) {
36 char *p = malloc(10);
37 if (!p) return 1;
38
39 // Out-of-bounds write (heap buffer overflow).
40 strcpy(p, "This string is way too long for the buffer");
41
42 // Use-after-free (unreachable if program aborts on previous error).
43 free(p);
44 p[0] = 'x';
45
46 return 0;
47}
48```
49
50Now let's compile with proper flags with `clang -O0 -g -fsanitize=address -o
51main main.c`.
52
53If you run the binary it should trigger ASan. You can also specify what to
54show with `ASAN_OPTIONS=detect_leaks=1:verbosity=1:symbolize=1 ./main` and you
55should see something like this.
56
57> By using any kind of optimization with `-On` will likely optimize the
58> problematic code out. But you can never be sure of it.
59
60```text
61MemToShadow(shadow): 0x00008fff7000 0x000091ff6dff 0x004091ff6e00 0x02008fff6fff
62redzone=16
63max_redzone=2048
64quarantine_size_mb=256M
65thread_local_quarantine_size_kb=1024K
66malloc_context_size=30
67SHADOW_SCALE: 3
68SHADOW_GRANULARITY: 8
69SHADOW_OFFSET: 0x00007fff8000
70==28825==Installed the sigaction for signal 11
71==28825==Installed the sigaction for signal 7
72==28825==Installed the sigaction for signal 8
73==28825==T0: FakeStack created: 0x7be4d10f7000 -- 0x7be4d1c00000 stack_size_log: 20; mmapped 11300K, noreserve=0
74==28825==T0: stack [0x7ffcf551c000,0x7ffcf5d1c000) size 0x800000; local=0x7ffcf5d1a664
75==28825==AddressSanitizer Init done
76=================================================================
77==28825==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7c04d25e001a at pc 0x5653c583826a bp 0x7ffcf5d1a5f0 sp 0x7ffcf5d19da8
78WRITE of size 43 at 0x7c04d25e001a thread T0
79 #0 0x5653c5838269 in strcpy (/home/m/Junk/fsanitize/main+0xb7269) (BuildId: 69a0723cc8e27d59eb584f6cc902f6f12915111a)
80 #1 0x5653c5894e13 in main /home/m/Junk/fsanitize/main.c:10:5
81 #2 0x7fe4d328bbfb in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
82 #3 0x7fe4d328bcb4 in __libc_start_main@GLIBC_2.2.5 csu/../csu/libc-start.c:360:3
83 #4 0x5653c57ad360 in _start /builddir/glibc-2.41/csu/../sysdeps/x86_64/start.S:115
84
850x7c04d25e001a is located 0 bytes after 10-byte region [0x7c04d25e0010,0x7c04d25e001a)
86allocated by thread T0 here:
87 #0 0x5653c5851ca4 in malloc (/home/m/Junk/fsanitize/main+0xd0ca4) (BuildId: 69a0723cc8e27d59eb584f6cc902f6f12915111a)
88 #1 0x5653c5894de8 in main /home/m/Junk/fsanitize/main.c:6:15
89 #2 0x7fe4d328bbfb in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
90
91SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/m/Junk/fsanitize/main+0xb7269) (BuildId: 69a0723cc8e27d59eb584f6cc902f6f12915111a) in strcpy
92Shadow bytes around the buggy address:
93 0x7c04d25dfd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
94 0x7c04d25dfe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
95 0x7c04d25dfe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
96 0x7c04d25dff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
97 0x7c04d25dff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
98=>0x7c04d25e0000: fa fa 00[02]fa fa fa fa fa fa fa fa fa fa fa fa
99 0x7c04d25e0080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
100 0x7c04d25e0100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
101 0x7c04d25e0180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
102 0x7c04d25e0200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
103 0x7c04d25e0280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
104Shadow byte legend (one shadow byte represents 8 application bytes):
105 Addressable: 00
106 Partially addressable: 01 02 03 04 05 06 07
107 Heap left redzone: fa
108 Freed heap region: fd
109 Stack left redzone: f1
110 Stack mid redzone: f2
111 Stack right redzone: f3
112 Stack after return: f5
113 Stack use after scope: f8
114 Global redzone: f9
115 Global init order: f6
116 Poisoned by user: f7
117 Container overflow: fc
118 Array cookie: ac
119 Intra object redzone: bb
120 ASan internal: fe
121 Left alloca redzone: ca
122 Right alloca redzone: cb
123==28825==ABORTING
124```