Skip to content

Commit 3cea392

Browse files
committed
emux: update to new ASAN spec
1 parent b34d648 commit 3cea392

4 files changed

Lines changed: 54 additions & 23 deletions

File tree

include/emux.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,27 @@
6666
#define EMUX_XASAN_POISON 0x2 ///< Poison a memory region
6767
#define EMUX_XASAN_UNPOISON 0x3 ///< Unpoison a memory region
6868

69-
#define EMUX_XASAN_TAG_USER 0 ///< User-poisoned region
69+
#define EMUX_XASAN_TAG_ACCESSIBLE 0 ///< Accessible region
7070
#define EMUX_XASAN_TAG_LEFT 1 ///< Left redzone
7171
#define EMUX_XASAN_TAG_RIGHT 2 ///< Right redzone
7272
#define EMUX_XASAN_TAG_FREED 3 ///< Freed memory
7373
#define EMUX_XASAN_TAG_GLOBAL 4 ///< Global redzone
74+
#define EMUX_XASAN_TAG_USER 5 ///< User-poisoned region
7475
#define EMUX_XASAN_TAG_UNALLOC 6 ///< Unallocated heap memory
7576

77+
#define EMUX_XASAN_ACCESS_UNKNOWN 0x00
78+
#define EMUX_XASAN_ACCESS_CPU_READ 0x01
79+
#define EMUX_XASAN_ACCESS_CPU_WRITE 0x02
80+
#define EMUX_XASAN_ACCESS_CPU_EXEC 0x03
81+
#define EMUX_XASAN_ACCESS_STACK 0x04
82+
#define EMUX_XASAN_ACCESS_RSP_DMA_READ 0x05
83+
#define EMUX_XASAN_ACCESS_RSP_DMA_WRITE 0x06
84+
85+
#define EMUX_XASAN_FAULT_UNKNOWN 0x00
86+
#define EMUX_XASAN_FAULT_PERMISSION 0x01
87+
#define EMUX_XASAN_FAULT_POISON 0x02
88+
#define EMUX_XASAN_FAULT_TAIL 0x03
89+
7690
#define EMUX_LOG_ASCIIZ 0x000 ///< Log a zero-terminated string
7791
#define EMUX_LOG_LENGTH 0x001 ///< Log a non-zero-terminated string
7892

src/asan.c

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#define ASAN_RIGHT_RZ 16
2727

2828
/** @brief Shadow / alignment granule (bytes) */
29-
#define ASAN_GRANULE 8
29+
#define ASAN_GRANULE 16
3030

3131
/** @brief Block header size (bytes); must be a multiple of ASAN_GRANULE */
3232
#define ASAN_HEADER_SIZE 16
@@ -57,11 +57,6 @@ extern void *__real_sbrk_top(int incr);
5757
extern struct mallinfo __real_mallinfo(void);
5858
extern struct mallinfo __real__mallinfo_r(struct _reent *r);
5959

60-
static inline size_t asan_round8(size_t n)
61-
{
62-
return (n + ASAN_GRANULE - 1) & ~(size_t)(ASAN_GRANULE - 1);
63-
}
64-
6560
static inline void *asan_align_ptr(void *p, size_t align)
6661
{
6762
uintptr_t v = (uintptr_t)p;
@@ -88,9 +83,7 @@ static bool asan_valid_hdr(const asan_hdr_t *hdr)
8883
static void asan_poison_region(const void *addr, size_t size, void (*poison_fn)(const void *, size_t))
8984
{
9085
if (!size) return;
91-
uintptr_t base = (uintptr_t)addr & ~(uintptr_t)(ASAN_GRANULE - 1);
92-
uintptr_t end = ((uintptr_t)addr + size + ASAN_GRANULE - 1) & ~(uintptr_t)(ASAN_GRANULE - 1);
93-
poison_fn((const void *)base, end - base);
86+
poison_fn(addr, size);
9487
}
9588

9689
void asan_poison(void *ptr, size_t size)
@@ -132,8 +125,8 @@ void *__wrap__malloc_r(struct _reent *r, size_t n)
132125
return __real__malloc_r(r, n);
133126
}
134127

135-
size_t payload_size = asan_round8(n);
136-
size_t total = ASAN_PAYLOAD_OFFSET + payload_size + ASAN_RIGHT_RZ;
128+
size_t payload_size = n;
129+
size_t total = ASAN_PAYLOAD_OFFSET + ASAN_GRANULE - 1 + payload_size + ASAN_RIGHT_RZ;
137130
void *raw;
138131
void *payload;
139132
asan_hdr_t *hdr;
@@ -145,7 +138,7 @@ void *__wrap__malloc_r(struct _reent *r, size_t n)
145138
return NULL;
146139
}
147140

148-
payload = (char *)raw + ASAN_PAYLOAD_OFFSET;
141+
payload = asan_align_ptr((char *)raw + ASAN_PAYLOAD_OFFSET, ASAN_GRANULE);
149142
hdr = asan_hdr(payload);
150143
asan_write_hdr(hdr, raw, n);
151144
emux_xasan_enable();
@@ -171,7 +164,7 @@ void __wrap__free_r(struct _reent *r, void *p)
171164
emux_xasan_disable();
172165
if (asan_valid_hdr(hdr)) {
173166
void *raw = hdr->raw;
174-
size_t payload_size = asan_round8(hdr->req_size);
167+
size_t payload_size = hdr->req_size;
175168
size_t total = (char *)p + payload_size + ASAN_RIGHT_RZ - (char *)raw;
176169
emux_xasan_poison_freed(raw, total);
177170
__real__free_r(r, raw);
@@ -221,7 +214,7 @@ void *__wrap__memalign_r(struct _reent *r, size_t align, size_t n)
221214
if (align < ASAN_GRANULE)
222215
align = ASAN_GRANULE;
223216

224-
size_t payload_size = asan_round8(n);
217+
size_t payload_size = n;
225218
size_t total = ASAN_PAYLOAD_OFFSET + align - 1 + payload_size + ASAN_RIGHT_RZ;
226219
void *raw;
227220
void *payload;

src/exception.c

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "console.h"
1111
#include "n64sys.h"
1212
#include "debug.h"
13+
#include "emux.h"
1314
#include "regsinternal.h"
1415
#include "kernel/kernel_internal.h"
1516
#include "kernel/ktls_internal.h"
@@ -466,21 +467,43 @@ static const char* __get_exception_name(exception_t *ex)
466467
uint32_t cacheerr = C0_CACHEERR();
467468
uint32_t kind = cacheerr & 0xFF;
468469
uint32_t tag = (cacheerr >> 8) & 0xFF;
470+
uint32_t access = (cacheerr >> 16) & 0xFF;
471+
uint32_t fault = (cacheerr >> 24) & 0xFF;
472+
static char emux_info[128];
469473
C0_WRITE_CACHEERR(0);
470474
switch (kind) {
471475
case 0: return "Cached access to non-RDRAM area";
472476
case 1: return "64-bit read from non-RDRAM area";
473477
case 2: return "Access to RCP unmapped area";
474-
case 4:
478+
case 4: {
479+
const char *access_name = "memory access";
480+
const char *tag_name = "unknown poison";
481+
const char *fault_name = "unknown";
482+
switch (access) {
483+
case EMUX_XASAN_ACCESS_CPU_READ: access_name = "CPU Read"; break;
484+
case EMUX_XASAN_ACCESS_CPU_WRITE: access_name = "CPU Write"; break;
485+
case EMUX_XASAN_ACCESS_CPU_EXEC: access_name = "CPU Exec"; break;
486+
case EMUX_XASAN_ACCESS_STACK: access_name = "Stack access"; break;
487+
case EMUX_XASAN_ACCESS_RSP_DMA_READ: access_name = "RSP DMA Read"; break;
488+
case EMUX_XASAN_ACCESS_RSP_DMA_WRITE: access_name = "RSP DMA Write"; break;
489+
}
475490
switch (tag) {
476-
case 0xf1: return "ASAN: heap-buffer-underflow (left redzone)";
477-
case 0xf2: return "ASAN: heap-buffer-overflow (right redzone)";
478-
case 0xf3: return "ASAN: use-after-free";
479-
case 0xf4: return "ASAN: global-buffer-overflow";
480-
case 0xf6: return "ASAN: access to unallocated heap memory";
481-
case 0xf5: return "ASAN: access to poisoned region";
482-
default: return "ASAN: invalid memory access";
491+
case EMUX_XASAN_TAG_ACCESSIBLE: tag_name = "accessible memory"; break;
492+
case EMUX_XASAN_TAG_LEFT: tag_name = "left redzone"; break;
493+
case EMUX_XASAN_TAG_RIGHT: tag_name = "right redzone"; break;
494+
case EMUX_XASAN_TAG_FREED: tag_name = "freed memory"; break;
495+
case EMUX_XASAN_TAG_GLOBAL: tag_name = "global redzone"; break;
496+
case EMUX_XASAN_TAG_USER: tag_name = "poisoned region"; break;
497+
case EMUX_XASAN_TAG_UNALLOC: tag_name = "unallocated heap memory"; break;
498+
}
499+
switch (fault) {
500+
case EMUX_XASAN_FAULT_PERMISSION: fault_name = "permission"; break;
501+
case EMUX_XASAN_FAULT_POISON: fault_name = "poison"; break;
502+
case EMUX_XASAN_FAULT_TAIL: fault_name = "tail"; break;
483503
}
504+
snprintf(emux_info, sizeof(emux_info), "ASAN: %s to %s (%s)", access_name, tag_name, fault_name);
505+
return emux_info;
506+
}
484507
default: return "Unknown emux";
485508
}
486509
}

src/inspector.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,7 @@ void __inspector_cppexception(const char *exctype, const char *what) {
887887

888888
__attribute__((noreturn))
889889
void __inspector_stack_smashing(void) {
890+
emux_xasan_disable();
890891
asm volatile (
891892
"syscall 0x3\n"
892893
);

0 commit comments

Comments
 (0)