33#include "los_lms_pri.h"
36#define LMS_FREE_NODE_SIZE 16
52ATTRIBUTE_NO_SANITIZE_ADDRESS
void LmsMem2Shadow(uintptr_t memAddr, uintptr_t *shadowAddr, uint32_t *shadowOffset)
54 uint32_t memOffset = memAddr - USPACE_MAP_BASE;
56 *shadowOffset = ((memOffset % LMS_SHADOW_U8_REFER_BYTES) / LMS_SHADOW_U8_CELL_NUM) * LMS_SHADOW_BITS_PER_CELL;
62 while (node != NULL) {
63 if ((sdStartAddr >= node->
addr) && (sdEndAddr < node->
addr + node->
mapSize)) {
71ATTRIBUTE_NO_SANITIZE_ADDRESS
void LmsAddMapNode(uintptr_t sdStartAddr, uintptr_t sdEndAddr)
73 static uint32_t freeNodeIdx = 0;
76 uintptr_t shadowPageStartAddr = LMS_MEM_ALIGN_DOWN(sdStartAddr, 0x1000);
77 uintptr_t shadowPageEndAddr = LMS_MEM_ALIGN_UP(sdEndAddr, 0x1000);
81 while (node != NULL) {
82 if ((shadowPageStartAddr >= node->
addr) && (shadowPageStartAddr <= node->
addr + node->
mapSize)) {
89 if (expandNode != NULL) {
90 shadowPageStartAddr = expandNode->
addr + expandNode->
mapSize;
91 expandNode->
mapSize = shadowPageEndAddr - expandNode->
addr;
94 mapSize = shadowPageEndAddr - shadowPageStartAddr;
96 mmap((
void *)shadowPageStartAddr,
mapSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
97 if (mapPtr == (
void *)-1) {
98 LMS_OUTPUT_INFO(
"mmap error! file:%s line:%d\n", __FILE__, __LINE__);
103 if (expandNode != NULL) {
107 if (freeNodeIdx >= LMS_FREE_NODE_SIZE) {
108 LMS_OUTPUT_INFO(
"Add new mmap node error! file:%s line:%d\n", __FILE__, __LINE__);
114 newNode->
addr = shadowPageStartAddr;
120ATTRIBUTE_NO_SANITIZE_ADDRESS
void LmsSetShadowValue(uintptr_t startAddr, uintptr_t endAddr,
char value)
122 uintptr_t shadowStart;
124 uint32_t startOffset;
127 char shadowValueMask;
134 if (shadowStart == shadowEnd) {
137 shadowValueMask = LMS_SHADOW_MASK_U8;
139 (shadowValueMask << startOffset) & (~(shadowValueMask << (endOffset + LMS_SHADOW_BITS_PER_CELL)));
140 shadowValue = value & shadowValueMask;
141 *(
char *)shadowStart &= ~shadowValueMask;
142 *(
char *)shadowStart |= shadowValue;
145 if (startOffset > 0) {
146 shadowValueMask = LMS_SHADOW_MASK_U8;
147 shadowValueMask = shadowValueMask << startOffset;
148 shadowValue = value & shadowValueMask;
149 *(
char *)shadowStart &= ~shadowValueMask;
150 *(
char *)shadowStart |= shadowValue;
155 if (endOffset < (LMS_SHADOW_U8_CELL_NUM - 1) * LMS_SHADOW_BITS_PER_CELL) {
156 shadowValueMask = LMS_SHADOW_MASK_U8;
157 shadowValueMask &= ~(shadowValueMask << (endOffset + LMS_SHADOW_BITS_PER_CELL));
158 shadowValue = value & shadowValueMask;
159 *(
char *)shadowEnd &= ~shadowValueMask;
160 *(
char *)shadowEnd |= shadowValue;
164 if (shadowEnd + 1 > shadowStart) {
165 (
void)
__real_memset((
void *)shadowStart, value & LMS_SHADOW_MASK_U8, shadowEnd + 1 - shadowStart);
172 uintptr_t shadowAddr;
173 uint32_t shadowOffset;
177 *shadowValue = LMS_SHADOW_ACCESSABLE_U8;
181 *shadowValue = ((*(
char *)shadowAddr) >> shadowOffset) & LMS_SHADOW_MASK;
184ATTRIBUTE_NO_SANITIZE_ADDRESS
void LmsMallocMark(uintptr_t preRzStart, uintptr_t accessMemStart, uintptr_t nextRzStart,
192ATTRIBUTE_NO_SANITIZE_ADDRESS
void *
LmsTagMem(
void *ptr,
size_t origSize)
195 size_t mSize = malloc_usable_size(ptr);
196 uint32_t memOffset = (uintptr_t)ptr + mSize + OVERHEAD - USPACE_MAP_BASE;
197 uintptr_t shadowEndAddr =
g_shadowStartAddr + memOffset / LMS_SHADOW_U8_REFER_BYTES;
198 LMS_OUTPUT_INFO(
"SHADOW_BASE:%x g_shadowStartAddr:%x memOffset: %x\n", SHADOW_BASE,
g_shadowStartAddr, memOffset);
199 memOffset = (uintptr_t)ptr - OVERHEAD - USPACE_MAP_BASE;
200 uintptr_t shadowStartAddr =
g_shadowStartAddr + memOffset / LMS_SHADOW_U8_REFER_BYTES;
207 LmsMallocMark((uintptr_t)ptr - OVERHEAD, (uintptr_t)ptr, (uintptr_t)ptr + LMS_MEM_ALIGN_UP(origSize, LMS_RZ_SIZE),
208 (uintptr_t)((uintptr_t)ptr + mSize + OVERHEAD));
217 uint32_t shadowValue = -1;
234#define LMS_DUMP_OFFSET 4
235#define LMS_DUMP_RANGE_DOUBLE 2
237 LMS_OUTPUT_INFO(
"\nDump info around address [0x%8x]:\n",
addr);
238 uint32_t printY = LMS_DUMP_OFFSET * LMS_DUMP_RANGE_DOUBLE + 1;
239 uint32_t printX = LMS_MEM_BYTES_PER_SHADOW_CELL * LMS_DUMP_RANGE_DOUBLE;
240 uintptr_t dumpAddr =
addr -
addr % printX - LMS_DUMP_OFFSET * printX;
241 uint32_t shadowValue = 0;
242 uintptr_t shadowAddr = 0;
243 uint32_t shadowOffset = 0;
246 for (
int y = 0; y < printY; y++, dumpAddr += printX) {
252 uintptr_t maxShadowAddr;
253 uint32_t maxShadowOffset;
254 LmsMem2Shadow(dumpAddr + printX, &maxShadowAddr, &maxShadowOffset);
260 LMS_OUTPUT_INFO(
"\n\t[0x%x]: ", dumpAddr);
261 for (
int x = 0; x < printX; x++) {
262 if (dumpAddr + x ==
addr) {
263 LMS_OUTPUT_INFO(
"[%02x]", *(uint8_t *)(dumpAddr + x));
265 LMS_OUTPUT_INFO(
" %02x ", *(uint8_t *)(dumpAddr + x));
269 LMS_OUTPUT_INFO(
"|\t[0x%x | %2d]: ", shadowAddr, shadowOffset);
271 for (
int x = 0; x < printX; x += LMS_MEM_BYTES_PER_SHADOW_CELL) {
273 isCheckAddr = dumpAddr + x - (uintptr_t)
addr + LMS_MEM_BYTES_PER_SHADOW_CELL;
274 if (isCheckAddr > 0 && isCheckAddr <= LMS_MEM_BYTES_PER_SHADOW_CELL) {
275 LMS_OUTPUT_INFO(
"[%1x]", shadowValue);
277 LMS_OUTPUT_INFO(
" %1x ", shadowValue);
282 LMS_OUTPUT_INFO(
"\n");
287 uintptr_t shadowAddr;
288 uint32_t shadowOffset;
289 uint32_t shadowValue;
293 shadowValue = ((*(
char *)shadowAddr) >> shadowOffset) & LMS_SHADOW_MASK;
303 if (info->
shadowValue != LMS_SHADOW_ACCESSABLE_U8) {
313 case LMS_SHADOW_AFTERFREE:
314 LMS_OUTPUT_ERROR(
"Use after free error detected!\n");
316 case LMS_SHADOW_REDZONE:
317 LMS_OUTPUT_ERROR(
"Heap buffer overflow error detected!\n");
319 case LMS_SHADOW_ACCESSABLE:
320 LMS_OUTPUT_ERROR(
"No error!\n");
323 LMS_OUTPUT_ERROR(
"UnKnown Error detected!\n");
329 LMS_OUTPUT_ERROR(
"Illegal Double free address at: [0x%x]\n", info->
memAddr);
332 LMS_OUTPUT_ERROR(
"Illegal READ address at: [0x%x]\n", info->
memAddr);
335 LMS_OUTPUT_ERROR(
"Illegal WRITE address at: [0x%x]\n", info->
memAddr);
338 LMS_OUTPUT_ERROR(
"UnKnown Error mode at: [0x%x]\n", info->
memAddr);
342 LMS_OUTPUT_INFO(
"Shadow memory address: [0x%x : %d] Shadow memory value: [%d] \n", info->
shadowAddr,
345 LMS_OUTPUT_INFO(
"\n");
346 LMS_OUTPUT_INFO(
"%-25s%d\n",
"Accessable heap addr", LMS_SHADOW_ACCESSABLE);
347 LMS_OUTPUT_INFO(
"%-25s%d\n",
"Heap red zone", LMS_SHADOW_REDZONE);
348 LMS_OUTPUT_INFO(
"%-25s%d\n",
"Heap freed buffer", LMS_SHADOW_AFTERFREE);
349 LMS_OUTPUT_INFO(
"\n");
352ATTRIBUTE_NO_SANITIZE_ADDRESS
void LmsReportError(uintptr_t p,
size_t size, uint32_t errMod)
358 LMS_OUTPUT_ERROR(
"\n***** Lite Memory Sanitizer Error Detected *****\n");
362 LMS_OUTPUT_ERROR(
"***** Lite Memory Sanitizer Error Detected End *****\n");
367 if (LMS_CRASH_MODE > 0) {
376 if (
LmsCheckAddr((uintptr_t)dest) != LMS_SHADOW_ACCESSABLE_U8) {
377 LmsReportError((uintptr_t)dest, MEM_REGION_SIZE_1, STORE_ERRMODE);
381 if (
LmsCheckAddr((uintptr_t)src) != LMS_SHADOW_ACCESSABLE_U8) {
386 for (uint32_t i = 0; *(src + i) !=
'\0'; i++) {
387 if (
LmsCheckAddr((uintptr_t)dest + i + 1) != LMS_SHADOW_ACCESSABLE_U8) {
388 LmsReportError((uintptr_t)dest + i + 1, MEM_REGION_SIZE_1, STORE_ERRMODE);
392 if (
LmsCheckAddr((uintptr_t)src + i + 1) != LMS_SHADOW_ACCESSABLE_U8) {
393 LmsReportError((uintptr_t)src + i + 1, MEM_REGION_SIZE_1, LOAD_ERRMODE);
VOID __asan_load2_noabort(UINTPTR p)
VOID __asan_store16_noabort(UINTPTR p)
VOID __asan_store4_noabort(UINTPTR p)
VOID __asan_loadN_noabort(UINTPTR p, UINT32 size)
VOID __asan_load8_noabort(UINTPTR p)
VOID __asan_store1_noabort(UINTPTR p)
VOID __asan_storeN_noabort(UINTPTR p, UINT32 size)
VOID __asan_store2_noabort(UINTPTR p)
VOID __asan_load16_noabort(UINTPTR p)
VOID __asan_handle_no_return(VOID)
VOID __asan_store8_noabort(UINTPTR p)
VOID __asan_load4_noabort(UINTPTR p)
VOID __asan_load1_noabort(UINTPTR p)
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 void
ATTRIBUTE_NO_SANITIZE_ADDRESS uint32_t LmsCheckAddrRegion(uintptr_t addr, size_t size)
ATTRIBUTE_NO_SANITIZE_ADDRESS void * LmsTagMem(void *ptr, size_t origSize)
void LmsCheckValid(const char *dest, const char *src)
ATTRIBUTE_NO_SANITIZE_ADDRESS uint32_t LmsCheckAddr(uintptr_t addr)
struct MmapNode * g_mmapNode
struct MmapNode g_freeNode[LMS_FREE_NODE_SIZE]
ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsPrintMemInfo(uintptr_t addr)
ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsSetShadowValue(uintptr_t startAddr, uintptr_t endAddr, char value)
ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsGetShadowValue(uintptr_t addr, uint32_t *shadowValue)
ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsAddMapNode(uintptr_t sdStartAddr, uintptr_t sdEndAddr)
ATTRIBUTE_NO_SANITIZE_ADDRESS uint32_t LmsIsShadowAddrMapped(uintptr_t sdStartAddr, uintptr_t sdEndAddr)
ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsMem2Shadow(uintptr_t memAddr, uintptr_t *shadowAddr, uint32_t *shadowOffset)
static ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsPrintErrInfo(LmsAddrInfo *info, uint32_t errMod)
static ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsGetErrorInfo(uintptr_t addr, size_t size, LmsAddrInfo *info)
uint32_t g_shadowStartAddr
ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsReportError(uintptr_t p, size_t size, uint32_t errMod)
ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsMallocMark(uintptr_t preRzStart, uintptr_t accessMemStart, uintptr_t nextRzStart, uintptr_t RzEndAddr)
pthread_mutex_t g_lmsMutex
static ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsGetShadowInfo(uintptr_t memAddr, LmsAddrInfo *info)
static ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsLock(pthread_mutex_t *lock)
static ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsCrash(void)
static ATTRIBUTE_NO_SANITIZE_ADDRESS int LmsTrylock(pthread_mutex_t *lock)
void * __real_memset(void *, int, size_t)
static ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsUnlock(pthread_mutex_t *lock)