1/* @title: Address sanitization */
2#include <errno.h>
3#include <log.h>
4#include <stdbool.h>
5#include <stddef.h>
6#include <stdint.h>
7#include <types/types.h>
8
9#define ASAN_SHADOW_SCALE 3ULL /* 1 shadow byte per 8 real bytes */
10#define ASAN_SHADOW_OFFSET 0xDFFFFE0000000000
11
12/*
13 * offset = SHADOW_REGION_START - (COVERED_START >> SHADOW_SCALE)
14 * shadow = (addr >> scale) + offset */
15#define ASAN_SHADOW_ADDR(a) \
16 ((uintptr_t) (((uintptr_t) (a) >> ASAN_SHADOW_SCALE) + ASAN_SHADOW_OFFSET))
17#define ASAN_GRANULE (1ULL << ASAN_SHADOW_SCALE)
18#define ASAN_REDZONE 16 /* optional redzone per allocation */
19
20/* Shadow byte encoding, one per ASAN_GRANULE bytes of memory:
21 *
22 * 0 - whole granule accessible
23 * 1..7 first k bytes accessible
24 * >= 0x80 nothing in granule accessible */
25#define ASAN_POISON_VALUE 0xFF /* generic: never handed out */
26#define ASAN_POISON_HEAP_REDZONE 0xFA /* slack around/inside a live slot */
27#define ASAN_POISON_HEAP_FREED 0xFD /* was live, has been freed */
28
29static inline bool asan_shadow_is_poison(uint8_t s) {
30 return s >= 0x80;
31}
32
33#define ASAN_ABORT_IF_NOT_READY() \
34 do { \
35 if (!asan_ready) \
36 return; \
37 } while (0)
38
39LOG_SITE_EXTERN(asan);
40LOG_HANDLE_EXTERN(asan);
41
42#define asan_log(lvl, fmt, ...) \
43 log(LOG_SITE(asan), LOG_HANDLE(asan), lvl, fmt, ##__VA_ARGS__)
44
45#define asan_err(fmt, ...) asan_log(LOG_ERROR, fmt, ##__VA_ARGS__)
46#define asan_warn(fmt, ...) asan_log(LOG_WARN, fmt, ##__VA_ARGS__)
47#define asan_info(fmt, ...) asan_log(LOG_INFO, fmt, ##__VA_ARGS__)
48#define asan_debug(fmt, ...) asan_log(LOG_DEBUG, fmt, ##__VA_ARGS__)
49#define asan_trace(fmt, ...) asan_log(LOG_TRACE, fmt, ##__VA_ARGS__)
50
51#ifdef DEBUG_ASAN
52
53void asan_init(void);
54
55/* Shadow backing at the slab chunk granularity, which must happen before any
56 * object in the chunk is handed off */
57enum errno asan_shadow_install(vaddr_t base, size_t len);
58void asan_shadow_release(vaddr_t base, size_t len);
59
60void asan_alloc(void *addr, size_t requested, size_t slot);
61void asan_free(void *addr, size_t slot);
62void asan_poison(void *addr, size_t size);
63void asan_unpoison(void *addr, size_t size);
64
65#else
66
67static inline void asan_init(void) {}
68
69static inline enum errno asan_shadow_install(vaddr_t base, size_t len) {
70 (void) base;
71 (void) len;
72 return ERR_OK;
73}
74
75static inline void asan_shadow_release(vaddr_t base, size_t len) {
76 (void) base;
77 (void) len;
78}
79
80static inline void asan_alloc(void *addr, size_t requested, size_t slot) {
81 (void) addr;
82 (void) requested;
83 (void) slot;
84}
85
86static inline void asan_free(void *addr, size_t slot) {
87 (void) addr;
88 (void) slot;
89}
90
91static inline void asan_poison(void *addr, size_t size) {
92 (void) addr;
93 (void) size;
94}
95
96static inline void asan_unpoison(void *addr, size_t size) {
97 (void) addr;
98 (void) size;
99}
100
101#endif
102