提交 3e7cfaa5 编写于 作者: O openharmony_ci 提交者: Gitee

!708 feat: L0-L1 支持Lms轻量级地址消毒

Merge pull request !708 from LiteOS/lms
......@@ -55,4 +55,8 @@ group("apps") {
if (defined(LOSCFG_DRIVERS_PERF)) {
deps += [ "perf" ]
}
if (defined(LOSCFG_KERNEL_LMS)) {
deps += [ "lms:sample_usr_lms" ]
}
}
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import("//build/lite/config/component/lite_component.gni")
lite_component("LMS-Sample") {
features = [ ":sample_usr_lms" ]
}
executable("sample_usr_lms") {
output_name = "sample_usr_lms"
sources = [ "src/sample_usr_lms.c" ]
include_dirs = []
defines = []
if (ohos_build_compiler == "gcc") {
cflags_c = [
"-O0",
"-fsanitize=kernel-address",
"-funwind-tables",
"-fasynchronous-unwind-tables",
]
} else {
cflags_c = [
"-O0",
"-fsanitize=kernel-address",
"-mllvm",
"-asan-instrumentation-with-call-threshold=0",
"-mllvm",
"-asan-stack=0",
"-mllvm",
"-asan-globals=0",
"-funwind-tables",
"-fasynchronous-unwind-tables",
]
}
ldflags = [
"-rdynamic",
"-lunwind",
"-lusrlms",
"-Wl,--wrap=realloc",
"-Wl,--wrap=calloc",
"-Wl,--wrap=malloc",
"-Wl,--wrap=free",
"-Wl,--wrap=valloc",
"-Wl,--wrap=aligned_alloc",
"-Wl,--wrap=memset",
"-Wl,--wrap=memcpy",
"-Wl,--wrap=memmove",
"-Wl,--wrap=strcpy",
"-Wl,--wrap=strcat",
]
deps = [ "//kernel/liteos_a/kernel/extended/lms/usr:usrlmslib" ]
}
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void BufWriteTest(void *buf, int start, int end)
{
for (int i = start; i <= end; i++) {
((char *)buf)[i] = 'a';
}
}
static void BufReadTest(void *buf, int start, int end)
{
char tmp;
for (int i = start; i <= end; i++) {
tmp = ((char *)buf)[i];
}
}
static void LmsMallocTest(void)
{
printf("\n-------- LmsMallocTest Start --------\n");
char *buf = (char *)malloc(16);
printf("[LmsMallocTest] malloc addr:%p size:%d\n", buf, 16);
printf("[LmsMallocTest] read overflow & underflow error should be triggered, read range[-1,16]\n");
BufReadTest(buf, -1, 16);
printf("[LmsMallocTest] write overflow error should be triggered, write range[0,16]\n");
BufWriteTest(buf, 0, 16);
free(buf);
printf("\n-------- LmsMallocTest End --------\n");
}
static void LmsReallocTest(void)
{
printf("\n-------- LmsReallocTest Start --------\n");
char *buf = (char *)malloc(64);
printf("[LmsReallocTest] malloc addr:%p size:%d\n", buf, 64);
printf("[LmsReallocTest] read overflow & underflow error should be triggered, read range[-1,64]\n");
BufReadTest(buf, -1, 64);
buf = (char *)realloc(buf, 32);
printf("[LmsReallocTest] realloc addr:%p size:%d\n", buf, 32);
printf("[LmsReallocTest] read overflow & underflow error should be triggered, read range[-1,32]\n");
BufReadTest(buf, -1, 32);
free(buf);
printf("\n-------- LmsReallocTest End --------\n");
}
static void LmsCallocTest(void)
{
printf("\n-------- LmsCallocTest Start --------\n");
char *buf = (char *)calloc(4, 4);
printf("[LmsCallocTest] calloc addr:%p size:%d\n", buf, 16);
printf("[LmsCallocTest] read overflow & underflow error should be triggered, read range[-1,16]\n");
BufReadTest(buf, -1, 16);
free(buf);
printf("\n-------- LmsCallocTest End --------\n");
}
static void LmsVallocTest(void)
{
printf("\n-------- LmsVallocTest Start --------\n");
char *buf = (char *)valloc(4096);
printf("[LmsVallocTest] valloc addr:%p size:%d\n", buf, 4096);
printf("[LmsVallocTest] read overflow & underflow error should be triggered, read range[-1,4096]\n");
BufReadTest(buf, -1, 4096);
free(buf);
printf("\n-------- LmsVallocTest End --------\n");
}
static void LmsAlignedAllocTest(void)
{
printf("\n-------- LmsAlignedAllocTest Start --------\n");
char *buf = (char *)aligned_alloc(64, 128);
printf("[LmsAlignedAllocTest] aligned_alloc boundsize:%d addr:%p size:%d\n", 64, buf, 128);
printf("[LmsAlignedAllocTest] read overflow & underflow error should be triggered, read range[-1,128]\n");
BufReadTest(buf, -1, 128);
free(buf);
printf("\n-------- LmsAlignedAllocTest End --------\n");
}
static void LmsMemsetTest(void)
{
printf("\n-------- LmsMemsetTest Start --------\n");
char *buf = (char *)malloc(32);
printf("[LmsMemsetTest] malloc addr:%p size:%d\n", buf, 32);
printf("[LmsMemsetTest] memset overflow & underflow error should be triggered, memset size:%d\n", 33);
memset(buf, 0, 33);
free(buf);
printf("\n-------- LmsMemsetTest End --------\n");
}
static void LmsMemcpyTest(void)
{
printf("\n-------- LmsMemcpyTest Start --------\n");
char *buf = (char *)malloc(20);
printf("[LmsMemcpyTest] malloc addr:%p size:%d\n", buf, 20);
char localBuf[32] = {0};
printf("[LmsMemcpyTest] memcpy overflow error should be triggered, memcpy size:%d\n", 21);
memcpy(buf, localBuf, 21);
free(buf);
printf("\n-------- LmsMemcpyTest End --------\n");
}
static void LmsMemmoveTest(void)
{
printf("\n-------- LmsMemmoveTest Start --------\n");
char *buf = (char *)malloc(20);
printf("[LmsMemmoveTest] malloc addr:%p size:%d\n", buf, 20);
printf("[LmsMemmoveTest] memmove overflow error should be triggered, dest addr:%p src addr:%p size:%d\n", buf + 12,
buf, 10);
memmove(buf + 12, buf, 10);
free(buf);
printf("\n-------- LmsMemmoveTest End --------\n");
}
static void LmsStrcpyTest(void)
{
printf("\n-------- LmsStrcpyTest Start --------\n");
char *buf = (char *)malloc(16);
printf("[LmsStrcpyTest] malloc addr:%p size:%d\n", buf, 16);
char *testStr = "bbbbbbbbbbbbbbbbb";
printf("[LmsStrcpyTest] strcpy overflow error should be triggered, src string buf size:%d\n", strlen(testStr) + 1);
strcpy(buf, testStr);
free(buf);
printf("\n-------- LmsStrcpyTest End --------\n");
}
static void LmsStrcatTest(void)
{
printf("\n-------- LmsStrcatTest Start --------\n");
char *buf = (char *)malloc(16);
printf("[LmsStrcatTest] malloc addr:%p size:%d\n", buf, 16);
buf[0] = 'a';
buf[1] = 'b';
buf[2] = 0;
char *testStr = "cccccccccccccc";
printf("[LmsStrcatTest] strcat overflow error should be triggered, src string:%s dest string:%s"
"total buf size:%d\n",
testStr, buf, strlen(testStr) + strlen(buf) + 1);
strcat(buf, testStr);
free(buf);
printf("\n-------- LmsStrcatTest End --------\n");
}
static void LmsFreeTest(void)
{
printf("\n-------- LmsFreeTest Start --------\n");
char *buf = (char *)malloc(16);
printf("[LmsFreeTest] malloc addr:%p size:%d\n", buf, 16);
printf("[LmsFreeTest] free addr:%p\n", buf, 16);
free(buf);
printf("[LmsFreeTest] Use after free error should be triggered, read addr:%p range[1,1]\n", buf);
BufReadTest(buf, 1, 1);
printf("[LmsFreeTest] double free error should be triggered, free addr:%p\n", buf);
free(buf);
printf("\n-------- LmsFreeTest End --------\n");
}
int main(int argc, char * const * argv)
{
printf("\n############### Lms Test start ###############\n");
char *tmp = (char *)malloc(5000);
LmsMallocTest();
LmsReallocTest();
LmsCallocTest();
LmsVallocTest();
LmsAlignedAllocTest();
LmsMemsetTest();
LmsMemcpyTest();
LmsMemmoveTest();
LmsStrcpyTest();
LmsStrcatTest();
LmsFreeTest();
printf("\n############### Lms Test End ###############\n");
}
\ No newline at end of file
......@@ -525,7 +525,9 @@ LITE_OS_SEC_TEXT VOID OsTaskResourcesToFree(LosTaskCB *taskCB)
OsTaskKernelResourcesToFree(syncSignal, topOfStack);
SCHEDULER_LOCK(intSave);
#ifdef LOSCFG_KERNEL_VM
OsClearSigInfoTmpList(&(taskCB->sig));
#endif
OsInsertTCBToFreeList(taskCB);
SCHEDULER_UNLOCK(intSave);
}
......
......@@ -88,6 +88,7 @@ STATIC INLINE VOID OsSchedIrqStartTime(VOID)
} while (0);
#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))
#define OS_SCHEDULER_ALL_ACTIVE (g_taskScheduled == LOSCFG_KERNEL_CPU_MASK)
typedef enum {
INT_NO_RESCH = 0x0, /* no needs to schedule */
......
......@@ -183,7 +183,14 @@ STATIC INLINE BOOL OsIsPageShared(LosVmPage *page)
return BIT_GET(page->flags, FILE_PAGE_SHARED);
}
typedef struct ProcessCB LosProcessCB;
#ifdef LOSCFG_FS_VFS
INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region);
STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region);
VOID OsVmmFileRegionFree(struct file *filep, LosProcessCB *processCB);
#endif
LosFilePage *OsPageCacheAlloc(struct page_mapping *mapping, VM_OFFSET_T pgoff);
LosFilePage *OsFindGetEntry(struct page_mapping *mapping, VM_OFFSET_T pgoff);
LosMapInfo *OsGetMapInfo(LosFilePage *page, LosArchMmu *archMmu, VADDR_T vaddr);
......@@ -198,14 +205,11 @@ VOID OsLruCacheDel(LosFilePage *fpage);
LosFilePage *OsDumpDirtyPage(LosFilePage *oldPage);
VOID OsDoFlushDirtyPage(LosFilePage *fpage);
VOID OsDeletePageCacheLru(LosFilePage *page);
STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region);
VOID OsPageRefDecNoLock(LosFilePage *page);
VOID OsPageRefIncLocked(LosFilePage *page);
int OsTryShrinkMemory(size_t nPage);
VOID OsMarkPageDirty(LosFilePage *fpage, LosVmMapRegion *region, int off, int len);
typedef struct ProcessCB LosProcessCB;
VOID OsVmmFileRegionFree(struct file *filep, LosProcessCB *processCB);
#ifdef LOSCFG_DEBUG_VERSION
VOID ResetPageCacheHitInfo(int *try, int *hit);
struct file_map* GetFileMappingList(void);
......
......@@ -39,6 +39,10 @@
#include "los_task_pri.h"
#include "los_hook.h"
#ifdef LOSCFG_KERNEL_LMS
#include "los_lms_pri.h"
#endif
/* Used to cut non-essential functions. */
#define OS_MEM_FREE_BY_TASKID 0
#ifdef LOSCFG_KERNEL_VM
......@@ -366,7 +370,9 @@ STATIC INLINE BOOL TryShrinkPool(const VOID *pool, const struct OsMemNodeHead *n
PRINT_ERR("TryShrinkPool free %#x failed!\n", node);
return FALSE;
}
#ifdef LOSCFG_KERNEL_LMS
LOS_LmsCheckPoolDel(node);
#endif
return TRUE;
}
......@@ -394,13 +400,24 @@ RETRY:
PRINT_ERR("OsMemPoolExpand alloc failed size = %u\n", size);
return -1;
}
#ifdef LOSCFG_KERNEL_LMS
UINT32 resize = 0;
if (g_lms != NULL) {
/*
* resize == 0, shadow memory init failed, no shadow memory for this pool, set poolSize as original size.
* resize != 0, shadow memory init successful, set poolSize as resize.
*/
resize = g_lms->init(newNode, size);
size = (resize == 0) ? size : resize;
}
#endif
newNode->sizeAndFlag = (size - OS_MEM_NODE_HEAD_SIZE);
newNode->ptr.prev = OS_MEM_END_NODE(newNode, size);
OsMemSentinelNodeSet(endNode, newNode, size);
OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)newNode);
endNode = OS_MEM_END_NODE(newNode, size);
(VOID)memset_s(endNode, sizeof(*endNode), 0, sizeof(*endNode));
(VOID)memset(endNode, 0, sizeof(*endNode));
endNode->ptr.next = NULL;
endNode->magic = OS_MEM_NODE_MAGIC;
OsMemSentinelNodeSet(endNode, NULL, 0);
......@@ -441,6 +458,71 @@ VOID LOS_MemExpandEnable(VOID *pool)
}
#endif
#ifdef LOSCFG_KERNEL_LMS
STATIC INLINE VOID OsLmsFirstNodeMark(VOID *pool, struct OsMemNodeHead *node)
{
if (g_lms == NULL) {
return;
}
g_lms->simpleMark((UINTPTR)pool, (UINTPTR)node, LMS_SHADOW_PAINT_U8);
g_lms->simpleMark((UINTPTR)node, (UINTPTR)node + OS_MEM_NODE_HEAD_SIZE, LMS_SHADOW_REDZONE_U8);
g_lms->simpleMark((UINTPTR)OS_MEM_NEXT_NODE(node), (UINTPTR)OS_MEM_NEXT_NODE(node) + OS_MEM_NODE_HEAD_SIZE,
LMS_SHADOW_REDZONE_U8);
g_lms->simpleMark((UINTPTR)node + OS_MEM_NODE_HEAD_SIZE, (UINTPTR)OS_MEM_NEXT_NODE(node),
LMS_SHADOW_AFTERFREE_U8);
}
STATIC INLINE VOID OsLmsAllocAlignMark(VOID *ptr, VOID *alignedPtr, UINT32 size)
{
struct OsMemNodeHead *allocNode = NULL;
if ((g_lms == NULL) || (ptr == NULL)) {
return;
}
allocNode = (struct OsMemNodeHead *)((struct OsMemUsedNodeHead *)ptr - 1);
if (ptr != alignedPtr) {
g_lms->simpleMark((UINTPTR)ptr, (UINTPTR)ptr + sizeof(UINT32), LMS_SHADOW_PAINT_U8);
g_lms->simpleMark((UINTPTR)ptr + sizeof(UINT32), (UINTPTR)alignedPtr, LMS_SHADOW_REDZONE_U8);
}
/* mark remining as redzone */
g_lms->simpleMark(LMS_ADDR_ALIGN((UINTPTR)alignedPtr + size), (UINTPTR)OS_MEM_NEXT_NODE(allocNode),
LMS_SHADOW_REDZONE_U8);
}
STATIC INLINE VOID OsLmsReallocMergeNodeMark(struct OsMemNodeHead *node)
{
if (g_lms == NULL) {
return;
}
g_lms->simpleMark((UINTPTR)node + OS_MEM_NODE_HEAD_SIZE, (UINTPTR)OS_MEM_NEXT_NODE(node),
LMS_SHADOW_ACCESSABLE_U8);
}
STATIC INLINE VOID OsLmsReallocSplitNodeMark(struct OsMemNodeHead *node)
{
if (g_lms == NULL) {
return;
}
/* mark next node */
g_lms->simpleMark((UINTPTR)OS_MEM_NEXT_NODE(node),
(UINTPTR)OS_MEM_NEXT_NODE(node) + OS_MEM_NODE_HEAD_SIZE, LMS_SHADOW_REDZONE_U8);
g_lms->simpleMark((UINTPTR)OS_MEM_NEXT_NODE(node) + OS_MEM_NODE_HEAD_SIZE,
(UINTPTR)OS_MEM_NEXT_NODE(OS_MEM_NEXT_NODE(node)), LMS_SHADOW_AFTERFREE_U8);
}
STATIC INLINE VOID OsLmsReallocResizeMark(struct OsMemNodeHead *node, UINT32 resize)
{
if (g_lms == NULL) {
return;
}
/* mark remaining as redzone */
g_lms->simpleMark((UINTPTR)node + resize, (UINTPTR)OS_MEM_NEXT_NODE(node), LMS_SHADOW_REDZONE_U8);
}
#endif
#ifdef LOSCFG_MEM_LEAKCHECK
STATIC INLINE VOID OsMemLinkRegisterRecord(struct OsMemNodeHead *node)
{
......@@ -738,6 +820,12 @@ STATIC INLINE VOID *OsMemCreateUsedNode(VOID *addr)
OsMemNodeSetTaskID(node);
#endif
#ifdef LOSCFG_KERNEL_LMS
struct OsMemNodeHead *newNode = (struct OsMemNodeHead *)node;
if (g_lms != NULL) {
g_lms->mallocMark(newNode, OS_MEM_NEXT_NODE(newNode), OS_MEM_NODE_HEAD_SIZE);
}
#endif
return node + 1;
}
......@@ -746,8 +834,18 @@ STATIC UINT32 OsMemPoolInit(VOID *pool, UINT32 size)
struct OsMemPoolHead *poolHead = (struct OsMemPoolHead *)pool;
struct OsMemNodeHead *newNode = NULL;
struct OsMemNodeHead *endNode = NULL;
(VOID)memset_s(poolHead, sizeof(struct OsMemPoolHead), 0, sizeof(struct OsMemPoolHead));
#ifdef LOSCFG_KERNEL_LMS
UINT32 resize = 0;
if (g_lms != NULL) {
/*
* resize == 0, shadow memory init failed, no shadow memory for this pool, set poolSize as original size.
* resize != 0, shadow memory init successful, set poolSize as resize.
*/
resize = g_lms->init(pool, size);
size = (resize == 0) ? size : resize;
}
#endif
(VOID)memset(poolHead, 0, sizeof(struct OsMemPoolHead));
LOS_SpinInit(&poolHead->spinlock);
poolHead->info.pool = pool;
......@@ -775,14 +873,18 @@ STATIC UINT32 OsMemPoolInit(VOID *pool, UINT32 size)
poolHead->info.curUsedSize = sizeof(struct OsMemPoolHead) + OS_MEM_NODE_HEAD_SIZE;
poolHead->info.waterLine = poolHead->info.curUsedSize;
#endif
#ifdef LOSCFG_KERNEL_LMS
if (resize != 0) {
OsLmsFirstNodeMark(pool, newNode);
}
#endif
return LOS_OK;
}
#ifdef LOSCFG_MEM_MUL_POOL
STATIC VOID OsMemPoolDeinit(VOID *pool)
{
(VOID)memset_s(pool, sizeof(struct OsMemPoolHead), 0, sizeof(struct OsMemPoolHead));
(VOID)memset(pool, 0, sizeof(struct OsMemPoolHead));
}
STATIC UINT32 OsMemPoolAdd(VOID *pool, UINT32 size)
......@@ -1009,6 +1111,9 @@ VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary)
MEM_UNLOCK(poolHead, intSave);
alignedPtr = (VOID *)OS_MEM_ALIGN(ptr, boundary);
if (ptr == alignedPtr) {
#ifdef LOSCFG_KERNEL_LMS
OsLmsAllocAlignMark(ptr, alignedPtr, size);
#endif
break;
}
......@@ -1018,6 +1123,9 @@ VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary)
OS_MEM_NODE_SET_ALIGNED_FLAG(allocNode->header.sizeAndFlag);
OS_MEM_NODE_SET_ALIGNED_FLAG(gapSize);
*(UINT32 *)((UINTPTR)alignedPtr - sizeof(gapSize)) = gapSize;
#ifdef LOSCFG_KERNEL_LMS
OsLmsAllocAlignMark(ptr, alignedPtr, size);
#endif
ptr = alignedPtr;
} while (0);
......@@ -1141,6 +1249,13 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead
node->sizeAndFlag = OS_MEM_NODE_GET_SIZE(node->sizeAndFlag);
#ifdef LOSCFG_MEM_LEAKCHECK
OsMemLinkRegisterRecord(node);
#endif
#ifdef LOSCFG_KERNEL_LMS
struct OsMemNodeHead *nextNodeBackup = OS_MEM_NEXT_NODE(node);
struct OsMemNodeHead *curNodeBackup = node;
if (g_lms != NULL) {
g_lms->check((UINTPTR)node + OS_MEM_NODE_HEAD_SIZE, TRUE);
}
#endif
struct OsMemNodeHead *preNode = node->ptr.prev; /* merage preNode */
if ((preNode != NULL) && !OS_MEM_NODE_GET_USED_FLAG(preNode->sizeAndFlag)) {
......@@ -1166,7 +1281,11 @@ STATIC INLINE UINT32 OsMemFree(struct OsMemPoolHead *pool, struct OsMemNodeHead
}
#endif
OsMemFreeNodeAdd(pool, (struct OsMemFreeNodeHead *)node);
#ifdef LOSCFG_KERNEL_LMS
if (g_lms != NULL) {
g_lms->freeMark(curNodeBackup, nextNodeBackup, OS_MEM_NODE_HEAD_SIZE);
}
#endif
return ret;
}
......@@ -1219,6 +1338,11 @@ STATIC INLINE VOID OsMemReAllocSmaller(VOID *pool, UINT32 allocSize, struct OsMe
OS_MEM_NODE_SET_USED_FLAG(node->sizeAndFlag);
#ifdef LOSCFG_MEM_WATERLINE
poolInfo->info.curUsedSize -= nodeSize - allocSize;
#endif
#ifdef LOSCFG_KERNEL_LMS
OsLmsReallocSplitNodeMark(node);
} else {
OsLmsReallocResizeMark(node, allocSize);
#endif
}
OS_MEM_NODE_SET_USED_FLAG(node->sizeAndFlag);
......@@ -1233,8 +1357,16 @@ STATIC INLINE VOID OsMemMergeNodeForReAllocBigger(VOID *pool, UINT32 allocSize,
node->sizeAndFlag = nodeSize;
OsMemFreeNodeDelete(pool, (struct OsMemFreeNodeHead *)nextNode);
OsMemMergeNode(nextNode);
#ifdef LOSCFG_KERNEL_LMS
OsLmsReallocMergeNodeMark(node);
#endif
if ((allocSize + OS_MEM_NODE_HEAD_SIZE + OS_MEM_MIN_ALLOC_SIZE) <= node->sizeAndFlag) {
OsMemSplitNode(pool, node, allocSize);
#ifdef LOSCFG_KERNEL_LMS
OsLmsReallocSplitNodeMark(node);
} else {
OsLmsReallocResizeMark(node, allocSize);
#endif
}
OS_MEM_NODE_SET_USED_FLAG(node->sizeAndFlag);
OsMemWaterUsedRecord((struct OsMemPoolHead *)pool, node->sizeAndFlag - nodeSize);
......@@ -1757,7 +1889,7 @@ UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus)
return LOS_NOK;
}
(VOID)memset_s(poolStatus, sizeof(LOS_MEM_POOL_STATUS), 0, sizeof(LOS_MEM_POOL_STATUS));
(VOID)memset(poolStatus, 0, sizeof(LOS_MEM_POOL_STATUS));
struct OsMemNodeHead *tmpNode = NULL;
struct OsMemNodeHead *endNode = NULL;
......
......@@ -39,6 +39,7 @@ group("extended") {
"hilog",
"hook",
"liteipc",
"lms",
"perf",
"pipes",
"power",
......@@ -59,5 +60,6 @@ config("public") {
"pipes:public",
"vdso:public",
"perf:public",
"lms:public",
]
}
......@@ -99,3 +99,6 @@ source "kernel/extended/hidumper/Kconfig"
######################### config options of perf #########################
source "kernel/extended/perf/Kconfig"
######################### config options of lms #########################
source "kernel/extended/lms/Kconfig"
\ No newline at end of file
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import("//kernel/liteos_a/liteos.gni")
module_switch = defined(LOSCFG_KERNEL_LMS)
module_name = get_path_info(rebase_path("."), "name")
kernel_module(module_name) {
sources = [
"lms_libc.c",
"los_lms.c",
]
}
config("public") {
include_dirs = [ "." ]
}
config KERNEL_LMS
bool "Enable Lite Memory Sanitizer"
default n
depends on KERNEL_EXTKERNEL && DEBUG_VERSION && LIB_LIBC
help
Select y to build LiteOS with memory sanitizer.
config LMS_MAX_RECORD_POOL_NUM
int "Lms check pool max num"
default 50
depends on KERNEL_LMS
help
The Max num of lms check pool
config LMS_LOAD_CHECK
bool "Enable lms read check"
default y
depends on KERNEL_LMS
help
Select y to enable read check.
config LMS_STORE_CHECK
bool "Enable lms write check"
default y
depends on KERNEL_LMS
help
Select y to enable write check.
config LMS_CHECK_STRICT
bool "Enable lms strict check, byte-by-byte"
default n
depends on KERNEL_LMS
help
Select y to enable byte-by-byte check in lms
config LMS_LIBC_FULL_CHECK
bool "Enable libc all function do lms check"
default n
depends on KERNEL_LMS
help
Select y to enable libc full check
include $(LITEOSTOPDIR)/config.mk
MODULE_NAME := $(notdir $(shell pwd))
LOCAL_SRCS := $(wildcard *.c)
LOCAL_FLAGS := $(LOCAL_INCLUDE)
include $(MODULE)
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "string.h"
#include "los_lms_pri.h"
#undef memset
void *memset(void *addr, int c, size_t len)
{
__asan_storeN_noabort((UINTPTR)addr, len);
return __memset(addr, c, len);
}
#undef memmove
void *memmove(void *dest, const void *src, size_t len)
{
__asan_loadN_noabort((UINTPTR)src, len);
__asan_storeN_noabort((UINTPTR)dest, len);
return __memmove(dest, src, len);
}
#undef memcpy
void *memcpy(void *dest, const void *src, size_t len)
{
__asan_loadN_noabort((UINTPTR)src, len);
__asan_storeN_noabort((UINTPTR)dest, len);
return __memcpy(dest, src, len);
}
#undef strcat
char *strcat (char *s, const char *append)
{
if ((s == NULL) || (append == NULL)) {
return NULL;
}
CHAR *end = s;
size_t len = strlen(append);
for (; *end != '\0'; ++end) {
}
__asan_storeN_noabort((UINTPTR)end, len + 1);
__asan_loadN_noabort((UINTPTR)append, len + 1);
return __strcat(s, append);
}
#undef strcpy
char *strcpy(char *dest, const char *src)
{
if ((dest == NULL) || (src == NULL)) {
return NULL;
}
size_t len = strlen(src);
__asan_storeN_noabort((UINTPTR)dest, len + 1);
__asan_loadN_noabort((UINTPTR)src, len + 1);
return __strcpy(dest, src);
}
#undef strncat
char *strncat(char *dest, const char *src, size_t n)
{
if ((dest == NULL) || (src == NULL)) {
return NULL;
}
CHAR *end = dest;
size_t len = strlen(src);
size_t size = len > n ? n : len;
for (; *end != '\0'; ++end) {
}
__asan_storeN_noabort((UINTPTR)end, size + 1);
__asan_loadN_noabort((UINTPTR)src, size + 1);
return __strncat(dest, src, n);
}
#undef strncpy
char *strncpy(char *dest, const char *src, size_t n)
{
if ((dest == NULL) || (src == NULL)) {
return NULL;
}
size_t len = strlen(src);
size_t size = len > n ? n : len;
__asan_storeN_noabort((UINTPTR)dest, n);
__asan_loadN_noabort((UINTPTR)src, size + 1);
return __strncpy(dest, src, n);
}
\ No newline at end of file
此差异已折叠。
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LOS_LMS_PRI_H
#define _LOS_LMS_PRI_H
#include "los_lms.h"
#include "los_typedef.h"
#include "los_list.h"
#include "securec.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define COMMON_ERRMODE 3
#define FREE_ERRORMODE 2
#define STORE_ERRMODE 1
#define LOAD_ERRMODE 0
#define SANITIZER_INTERFACE_ATTRIBUTE
#define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
#define LMS_SHADOW_BITS_PER_CELL 2
#define LMS_MEM_BYTES_PER_SHADOW_CELL 4
#define LMS_SHADOW_U8_CELL_NUM 4
#define LMS_SHADOW_U8_REFER_BYTES 16
#define LMS_POOL_RESIZE(size) ((size) / (LMS_SHADOW_U8_REFER_BYTES + 1) * LMS_SHADOW_U8_REFER_BYTES)
#define LMS_ADDR_ALIGN(p) (((UINTPTR)(p) + sizeof(UINTPTR) - 1) & ~((UINTPTR)(sizeof(UINTPTR) - 1)))
#define LMS_SHADOW_ACCESSABLE 0x00
#define LMS_SHADOW_AFTERFREE 0x03
#define LMS_SHADOW_REDZONE 0x02
#define LMS_SHADOW_PAINT 0x01
#define LMS_SHADOW_MASK 0x03
#define LMS_SHADOW_ACCESSABLE_U8 0x00
#define LMS_SHADOW_AFTERFREE_U8 0xFF
#define LMS_SHADOW_REDZONE_U8 0xAA
#define LMS_SHADOW_MASK_U8 0xFF
#define LMS_SHADOW_PAINT_U8 0x55
#define MEM_REGION_SIZE_1 1
#define MEM_REGION_SIZE_2 2
#define MEM_REGION_SIZE_4 4
#define MEM_REGION_SIZE_8 8
#define MEM_REGION_SIZE_16 16
typedef struct {
LOS_DL_LIST node;
UINT32 used;
UINTPTR poolAddr;
UINT32 poolSize;
UINTPTR shadowStart;
UINT32 shadowSize;
} LmsMemListNode;
typedef struct {
UINTPTR memAddr;
UINTPTR shadowAddr;
UINT32 shadowOffset;
UINT32 shadowValue;
} LmsAddrInfo;
typedef struct {
UINT32 (*init)(const VOID *pool, UINT32 size);
VOID (*mallocMark)(const VOID *curNodeStart, const VOID *nextNodeStart, UINT32 nodeHeadSize);
VOID (*freeMark)(const VOID *curNodeStart, const VOID *nextNodeStart, UINT32 nodeHeadSize);
VOID (*simpleMark)(UINTPTR startAddr, UINTPTR endAddr, UINT32 value);
VOID (*check)(UINTPTR checkAddr, BOOL isFreeCheck);
} LmsHook;
extern LmsHook* g_lms;
VOID OsLmsCheckValid(UINTPTR checkAddr, BOOL isFreeCheck);
VOID OsLmsLosMallocMark(const VOID *curNodeStart, const VOID *nextNodeStart, UINT32 nodeHeadSize);
VOID OsLmsLosFreeMark(const VOID *curNodeStart, const VOID *nextNodeStart, UINT32 nodeHeadSize);
VOID OsLmsSimpleMark(UINTPTR startAddr, UINTPTR endAddr, UINT32 value);
VOID OsLmsPrintPoolListInfo(VOID);
VOID OsLmsReportError(UINTPTR p, UINT32 size, UINT32 errMod);
VOID CheckValid(const CHAR *dest, const CHAR *src);
extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_store1_noabort(UINTPTR p);
extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_store4_noabort(UINTPTR p);
extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_load4_noabort(UINTPTR p);
extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_load1_noabort(UINTPTR p);
extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_loadN_noabort(UINTPTR p, UINT32 size);
extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_storeN_noabort(UINTPTR p, UINT32 size);
extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_store2_noabort(UINTPTR p);
extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_load2_noabort(UINTPTR p);
extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_store8_noabort(UINTPTR p);
extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_load8_noabort(UINTPTR p);
extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_load16_noabort(UINTPTR p);
extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_store16_noabort(UINTPTR p);
extern SANITIZER_INTERFACE_ATTRIBUTE VOID __asan_handle_no_return(VOID);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_LMS_PRI_H */
\ No newline at end of file
# Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
# Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of
# conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
# of conditions and the following disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
# to endorse or promote products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import("//build/lite/config/component/lite_component.gni")
copy("usrlmslib") {
deps = [ ":usrlms" ]
sources = [ get_path_info(".", "out_dir") + "/libusrlms.a" ]
outputs = [ "$root_out_dir/libusrlms.a" ]
}
lite_library("usrlms") {
target_type = "static_library"
sources = [
"los_lms.c",
"los_lmslibc.c",
]
include_dirs = [ "." ]
cflags = [
"-fPIC",
"-funwind-tables",
"-fasynchronous-unwind-tables",
]
ldflags = [
"-rdynamic",
"-lunwind",
]
output_dir = target_out_dir
}
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/mman.h>
#include "los_lms_pri.h"
#include "debug.h"
#define LMS_FREE_NODE_SIZE 16
struct MmapNode {
uintptr_t addr;
size_t mapSize;
struct MmapNode *next;
};
struct MmapNode g_freeNode[LMS_FREE_NODE_SIZE];
struct MmapNode *g_mmapNode = NULL;
uint32_t g_shadowStartAddr = SHADOW_BASE;
pthread_mutex_t g_lmsMutex = PTHREAD_MUTEX_INITIALIZER;
ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsMem2Shadow(uintptr_t memAddr, uintptr_t *shadowAddr, uint32_t *shadowOffset)
{
uint32_t memOffset = memAddr - USPACE_MAP_BASE;
*shadowAddr = g_shadowStartAddr + memOffset / LMS_SHADOW_U8_REFER_BYTES;
*shadowOffset = ((memOffset % LMS_SHADOW_U8_REFER_BYTES) / LMS_SHADOW_U8_CELL_NUM) * LMS_SHADOW_BITS_PER_CELL;
}
ATTRIBUTE_NO_SANITIZE_ADDRESS uint32_t LmsIsShadowAddrMapped(uintptr_t sdStartAddr, uintptr_t sdEndAddr)
{
struct MmapNode *node = g_mmapNode;
while (node != NULL) {
if ((sdStartAddr >= node->addr) && (sdEndAddr < node->addr + node->mapSize)) {
return LMS_OK;
}
node = node->next;
}
return LMS_NOK;
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsAddMapNode(uintptr_t sdStartAddr, uintptr_t sdEndAddr)
{
static uint32_t freeNodeIdx = 0;
struct MmapNode *node = g_mmapNode;
size_t mapSize;
uintptr_t shadowPageStartAddr = LMS_MEM_ALIGN_DOWN(sdStartAddr, 0x1000);
uintptr_t shadowPageEndAddr = LMS_MEM_ALIGN_UP(sdEndAddr, 0x1000);
struct MmapNode *expandNode = NULL;
while (node != NULL) {
if ((shadowPageStartAddr >= node->addr) && (shadowPageStartAddr <= node->addr + node->mapSize)) {
expandNode = node;
break;
}
node = node->next;
}
if (expandNode != NULL) {
shadowPageStartAddr = expandNode->addr + expandNode->mapSize;
expandNode->mapSize = shadowPageEndAddr - expandNode->addr;
}
mapSize = shadowPageEndAddr - shadowPageStartAddr;
void *mapPtr =
mmap((void *)shadowPageStartAddr, mapSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (mapPtr == (void *)-1) {
LMS_OUTPUT_INFO("mmap error! file:%s line:%d\n", __FILE__, __LINE__);
return;
}
__real_memset(mapPtr, 0, mapSize);
if (expandNode != NULL) {
return;
}
if (freeNodeIdx >= LMS_FREE_NODE_SIZE) {
LMS_OUTPUT_INFO("Add new mmap node error! file:%s line:%d\n", __FILE__, __LINE__);
return;
}
struct MmapNode *newNode = &g_freeNode[freeNodeIdx];
freeNodeIdx++;
newNode->addr = shadowPageStartAddr;
newNode->mapSize = mapSize;
newNode->next = g_mmapNode;
g_mmapNode = newNode;
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsSetShadowValue(uintptr_t startAddr, uintptr_t endAddr, char value)
{
uintptr_t shadowStart;
uintptr_t shadowEnd;
uint32_t startOffset;
uint32_t endOffset;
char shadowValueMask;
char shadowValue;
/* endAddr - 1, then we mark [startAddr, endAddr) to value */
LmsMem2Shadow(startAddr, &shadowStart, &startOffset);
LmsMem2Shadow(endAddr - 1, &shadowEnd, &endOffset);
if (shadowStart == shadowEnd) { /* in the same u8 */
/* because endAddr - 1, the endOffset falls into the previous cell,
so endOffset + 2 is required for calculation */
shadowValueMask = LMS_SHADOW_MASK_U8;
shadowValueMask =
(shadowValueMask << startOffset) & (~(shadowValueMask << (endOffset + LMS_SHADOW_BITS_PER_CELL)));
shadowValue = value & shadowValueMask;
*(char *)shadowStart &= ~shadowValueMask;
*(char *)shadowStart |= shadowValue;
} else {
/* Adjust startAddr to left util it reach the beginning of a u8 */
if (startOffset > 0) {
shadowValueMask = LMS_SHADOW_MASK_U8;
shadowValueMask = shadowValueMask << startOffset;
shadowValue = value & shadowValueMask;
*(char *)shadowStart &= ~shadowValueMask;
*(char *)shadowStart |= shadowValue;
shadowStart += 1;
}
/* Adjust endAddr to right util it reach the end of a u8 */
if (endOffset < (LMS_SHADOW_U8_CELL_NUM - 1) * LMS_SHADOW_BITS_PER_CELL) {
shadowValueMask = LMS_SHADOW_MASK_U8;
shadowValueMask &= ~(shadowValueMask << (endOffset + LMS_SHADOW_BITS_PER_CELL));
shadowValue = value & shadowValueMask;
*(char *)shadowEnd &= ~shadowValueMask;
*(char *)shadowEnd |= shadowValue;
shadowEnd -= 1;
}
if (shadowEnd + 1 > shadowStart) {
(void)__real_memset((void *)shadowStart, value & LMS_SHADOW_MASK_U8, shadowEnd + 1 - shadowStart);
}
}
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsGetShadowValue(uintptr_t addr, uint32_t *shadowValue)
{
uintptr_t shadowAddr;
uint32_t shadowOffset;
LmsMem2Shadow(addr, &shadowAddr, &shadowOffset);
/* If the shadow addr is not mapped then regarded as legal access */
if (LmsIsShadowAddrMapped(shadowAddr, shadowAddr) != LMS_OK) {
*shadowValue = LMS_SHADOW_ACCESSABLE_U8;
return;
}
*shadowValue = ((*(char *)shadowAddr) >> shadowOffset) & LMS_SHADOW_MASK;
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsMallocMark(uintptr_t preRzStart, uintptr_t accessMemStart, uintptr_t nextRzStart,
uintptr_t RzEndAddr)
{
LmsSetShadowValue(preRzStart, accessMemStart, LMS_SHADOW_REDZONE_U8);
LmsSetShadowValue(accessMemStart, nextRzStart, LMS_SHADOW_ACCESSABLE_U8);
LmsSetShadowValue(nextRzStart, RzEndAddr, LMS_SHADOW_REDZONE_U8);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsTagMem(void *ptr, size_t origSize)
{
g_shadowStartAddr = SHADOW_BASE;
size_t mSize = malloc_usable_size(ptr);
uint32_t memOffset = (uintptr_t)ptr + mSize + OVERHEAD - USPACE_MAP_BASE;
uintptr_t shadowEndAddr = g_shadowStartAddr + memOffset / LMS_SHADOW_U8_REFER_BYTES;
LMS_OUTPUT_INFO("SHADOW_BASE:%x g_shadowStartAddr:%x memOffset: %x\n", SHADOW_BASE, g_shadowStartAddr, memOffset);
memOffset = (uintptr_t)ptr - OVERHEAD - USPACE_MAP_BASE;
uintptr_t shadowStartAddr = g_shadowStartAddr + memOffset / LMS_SHADOW_U8_REFER_BYTES;
LmsLock(&g_lmsMutex);
if (LmsIsShadowAddrMapped(shadowStartAddr, shadowEndAddr) != LMS_OK) {
LmsAddMapNode(shadowStartAddr, shadowEndAddr);
}
LmsMallocMark((uintptr_t)ptr - OVERHEAD, (uintptr_t)ptr, (uintptr_t)ptr + LMS_MEM_ALIGN_UP(origSize, LMS_RZ_SIZE),
(uintptr_t)((uintptr_t)ptr + mSize + OVERHEAD));
LmsUnlock(&g_lmsMutex);
return ptr;
}
ATTRIBUTE_NO_SANITIZE_ADDRESS uint32_t LmsCheckAddr(uintptr_t addr)
{
LmsLock(&g_lmsMutex);
uint32_t shadowValue = -1;
LmsGetShadowValue(addr, &shadowValue);
LmsUnlock(&g_lmsMutex);
return shadowValue;
}
ATTRIBUTE_NO_SANITIZE_ADDRESS uint32_t LmsCheckAddrRegion(uintptr_t addr, size_t size)
{
if (LmsCheckAddr(addr) || LmsCheckAddr(addr + size - 1)) {
return LMS_NOK;
} else {
return LMS_OK;
}
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsPrintMemInfo(uintptr_t addr)
{
#define LMS_DUMP_OFFSET 4
#define LMS_DUMP_RANGE_DOUBLE 2
LMS_OUTPUT_INFO("\nDump info around address [0x%8x]:\n", addr);
uint32_t printY = LMS_DUMP_OFFSET * LMS_DUMP_RANGE_DOUBLE + 1;
uint32_t printX = LMS_MEM_BYTES_PER_SHADOW_CELL * LMS_DUMP_RANGE_DOUBLE;
uintptr_t dumpAddr = addr - addr % printX - LMS_DUMP_OFFSET * printX;
uint32_t shadowValue = 0;
uintptr_t shadowAddr = 0;
uint32_t shadowOffset = 0;
int isCheckAddr;
for (int y = 0; y < printY; y++, dumpAddr += printX) {
LmsMem2Shadow(dumpAddr, &shadowAddr, &shadowOffset);
/* find util dumpAddr in pool region */
if (LmsIsShadowAddrMapped(shadowAddr, shadowAddr) != LMS_OK) {
continue;
}
uintptr_t maxShadowAddr;
uint32_t maxShadowOffset;
LmsMem2Shadow(dumpAddr + printX, &maxShadowAddr, &maxShadowOffset);
/* finish if dumpAddr exceeds pool's upper region */
if (LmsIsShadowAddrMapped(maxShadowAddr, maxShadowAddr) != LMS_OK) {
goto END;
}
LMS_OUTPUT_INFO("\n\t[0x%x]: ", dumpAddr);
for (int x = 0; x < printX; x++) {
if (dumpAddr + x == addr) {
LMS_OUTPUT_INFO("[%02x]", *(uint8_t *)(dumpAddr + x));
} else {
LMS_OUTPUT_INFO(" %02x ", *(uint8_t *)(dumpAddr + x));
}
}
LMS_OUTPUT_INFO("|\t[0x%x | %2d]: ", shadowAddr, shadowOffset);
for (int x = 0; x < printX; x += LMS_MEM_BYTES_PER_SHADOW_CELL) {
LmsGetShadowValue(dumpAddr + x, &shadowValue);
isCheckAddr = dumpAddr + x - (uintptr_t)addr + LMS_MEM_BYTES_PER_SHADOW_CELL;
if (isCheckAddr > 0 && isCheckAddr <= LMS_MEM_BYTES_PER_SHADOW_CELL) {
LMS_OUTPUT_INFO("[%1x]", shadowValue);
} else {
LMS_OUTPUT_INFO(" %1x ", shadowValue);
}
}
}
END:
LMS_OUTPUT_INFO("\n");
}
ATTRIBUTE_NO_SANITIZE_ADDRESS static inline void LmsGetShadowInfo(uintptr_t memAddr, LmsAddrInfo *info)
{
uintptr_t shadowAddr;
uint32_t shadowOffset;
uint32_t shadowValue;
LmsMem2Shadow(memAddr, &shadowAddr, &shadowOffset);
shadowValue = ((*(char *)shadowAddr) >> shadowOffset) & LMS_SHADOW_MASK;
info->memAddr = memAddr;
info->shadowAddr = shadowAddr;
info->shadowOffset = shadowOffset;
info->shadowValue = shadowValue;
}
ATTRIBUTE_NO_SANITIZE_ADDRESS static void LmsGetErrorInfo(uintptr_t addr, size_t size, LmsAddrInfo *info)
{
LmsGetShadowInfo(addr, info);
if (info->shadowValue != LMS_SHADOW_ACCESSABLE_U8) {
return;
} else {
LmsGetShadowInfo(addr + size - 1, info);
}
}
ATTRIBUTE_NO_SANITIZE_ADDRESS static void LmsPrintErrInfo(LmsAddrInfo *info, uint32_t errMod)
{
switch (info->shadowValue) {
case LMS_SHADOW_AFTERFREE:
LMS_OUTPUT_ERROR("Use after free error detected!\n");
break;
case LMS_SHADOW_REDZONE:
LMS_OUTPUT_ERROR("Heap buffer overflow error detected!\n");
break;
case LMS_SHADOW_ACCESSABLE:
LMS_OUTPUT_ERROR("No error!\n");
break;
default:
LMS_OUTPUT_ERROR("UnKnown Error detected!\n");
break;
}
switch (errMod) {
case FREE_ERRORMODE:
LMS_OUTPUT_ERROR("Illegal Double free address at: [0x%x]\n", info->memAddr);
break;
case LOAD_ERRMODE:
LMS_OUTPUT_ERROR("Illegal READ address at: [0x%x]\n", info->memAddr);
break;
case STORE_ERRMODE:
LMS_OUTPUT_ERROR("Illegal WRITE address at: [0x%x]\n", info->memAddr);
break;
default:
LMS_OUTPUT_ERROR("UnKnown Error mode at: [0x%x]\n", info->memAddr);
break;
}
LMS_OUTPUT_INFO("Shadow memory address: [0x%x : %d] Shadow memory value: [%d] \n", info->shadowAddr,
info->shadowOffset, info->shadowValue);
LMS_OUTPUT_INFO("\n");
LMS_OUTPUT_INFO("%-25s%d\n", "Accessable heap addr", LMS_SHADOW_ACCESSABLE);
LMS_OUTPUT_INFO("%-25s%d\n", "Heap red zone", LMS_SHADOW_REDZONE);
LMS_OUTPUT_INFO("%-25s%d\n", "Heap freed buffer", LMS_SHADOW_AFTERFREE);
LMS_OUTPUT_INFO("\n");
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsReportError(uintptr_t p, size_t size, uint32_t errMod)
{
LmsAddrInfo info;
(void)__real_memset(&info, 0, sizeof(LmsAddrInfo));
int locked = LmsTrylock(&g_lmsMutex);
LMS_OUTPUT_ERROR("\n***** Lite Memory Sanitizer Error Detected *****\n");
LmsGetErrorInfo(p, size, &info);
LmsPrintErrInfo(&info, errMod);
LmsPrintMemInfo(info.memAddr);
LMS_OUTPUT_ERROR("***** Lite Memory Sanitizer Error Detected End *****\n");
if (!locked) {
LmsUnlock(&g_lmsMutex);
}
if (LMS_CRASH_MODE > 0) {
LmsCrash();
} else {
print_trace();
}
}
void LmsCheckValid(const char *dest, const char *src)
{
if (LmsCheckAddr((uintptr_t)dest) != LMS_SHADOW_ACCESSABLE_U8) {
LmsReportError((uintptr_t)dest, MEM_REGION_SIZE_1, STORE_ERRMODE);
return;
}
if (LmsCheckAddr((uintptr_t)src) != LMS_SHADOW_ACCESSABLE_U8) {
LmsReportError((uintptr_t)src, MEM_REGION_SIZE_1, LOAD_ERRMODE);
return;
}
for (uint32_t i = 0; *(src + i) != '\0'; i++) {
if (LmsCheckAddr((uintptr_t)dest + i + 1) != LMS_SHADOW_ACCESSABLE_U8) {
LmsReportError((uintptr_t)dest + i + 1, MEM_REGION_SIZE_1, STORE_ERRMODE);
return;
}
if (LmsCheckAddr((uintptr_t)src + i + 1) != LMS_SHADOW_ACCESSABLE_U8) {
LmsReportError((uintptr_t)src + i + 1, MEM_REGION_SIZE_1, LOAD_ERRMODE);
return;
}
}
}
void __asan_store1_noabort(uintptr_t p)
{
if (LmsCheckAddr(p) != LMS_SHADOW_ACCESSABLE_U8) {
LmsReportError(p, MEM_REGION_SIZE_1, STORE_ERRMODE);
}
}
void __asan_store2_noabort(uintptr_t p)
{
if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_2) != LMS_OK) {
LmsReportError(p, MEM_REGION_SIZE_2, STORE_ERRMODE);
}
}
void __asan_store4_noabort(uintptr_t p)
{
if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_4) != LMS_OK) {
LmsReportError(p, MEM_REGION_SIZE_4, STORE_ERRMODE);
}
}
void __asan_store8_noabort(uintptr_t p)
{
if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_8) != LMS_OK) {
LmsReportError(p, MEM_REGION_SIZE_8, STORE_ERRMODE);
}
}
void __asan_store16_noabort(uintptr_t p)
{
if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_16) != LMS_OK) { /* 16 byte memory for check */
LmsReportError(p, MEM_REGION_SIZE_16, STORE_ERRMODE);
}
}
void __asan_storeN_noabort(uintptr_t p, size_t size)
{
if (LmsCheckAddrRegion(p, size) != LMS_OK) {
LmsReportError(p, size, STORE_ERRMODE);
}
}
void __asan_load1_noabort(uintptr_t p)
{
if (LmsCheckAddr(p) != LMS_SHADOW_ACCESSABLE_U8) {
LmsReportError(p, MEM_REGION_SIZE_1, LOAD_ERRMODE);
}
}
void __asan_load2_noabort(uintptr_t p)
{
if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_2) != LMS_OK) {
LmsReportError(p, MEM_REGION_SIZE_2, LOAD_ERRMODE);
}
}
void __asan_load4_noabort(uintptr_t p)
{
if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_4) != LMS_OK) {
LmsReportError(p, MEM_REGION_SIZE_4, LOAD_ERRMODE);
}
}
void __asan_load8_noabort(uintptr_t p)
{
if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_8) != LMS_OK) {
LmsReportError(p, MEM_REGION_SIZE_8, LOAD_ERRMODE);
}
}
void __asan_load16_noabort(uintptr_t p)
{
if (LmsCheckAddrRegion(p, MEM_REGION_SIZE_16) != LMS_OK) {
LmsReportError(p, MEM_REGION_SIZE_16, LOAD_ERRMODE);
}
}
void __asan_loadN_noabort(uintptr_t p, size_t size)
{
if (LmsCheckAddrRegion(p, size) != LMS_OK) {
LmsReportError(p, size, LOAD_ERRMODE);
}
}
void __asan_handle_no_return(void)
{
return;
}
\ No newline at end of file
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LOS_LMS_H
#define _LOS_LMS_H
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/*
* If LMS_CRASH_MODE == 0
* the program would NOT be crashed once the sanitizer detected an error.
* If LMS_CRASM_MODE > 0
* the program would be crashed once the sanitizer detected an error.
*/
#define LMS_CRASH_MODE 0
/*
* USPACE_MAP_BASE
* is the start address of user space.
*/
#define USPACE_MAP_BASE 0x00000000
/*
* USPACE_MAP_SIZE
* is the address size of the user space, and [USPACE_MAP_BASE, USPACE_MAP_BASE + USPACE_MAP_SIZE]
* must cover the HEAP section.
*/
#define USPACE_MAP_SIZE 0x3ef00000
/*
* LMS_OUTPUT_ERROR can be redefined to redirect output logs.
*/
#ifndef LMS_OUTPUT_ERROR
#define LMS_OUTPUT_ERROR(fmt, ...) \
do { \
(printf("\033[31;1m"), printf(fmt, ##__VA_ARGS__), printf("\033[0m")); \
} while (0)
#endif
/*
* LMS_OUTPUT_INFO can be redefined to redirect output logs.
*/
#ifndef LMS_OUTPUT_INFO
#define LMS_OUTPUT_INFO(fmt, ...) \
do { \
(printf("\033[33;1m"), printf(fmt, ##__VA_ARGS__), printf("\033[0m")); \
} while (0)
#endif
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_LMS_H */
\ No newline at end of file
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LOS_LMS_PRI_H
#define _LOS_LMS_PRI_H
#include <pthread.h>
#include <malloc.h>
#include "los_lms.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define UNKNOWN_ERROR 3
#define FREE_ERRORMODE 2
#define STORE_ERRMODE 1
#define LOAD_ERRMODE 0
#define SANITIZER_INTERFACE_ATTRIBUTE
#define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
#define LMS_SHADOW_ACCESSABLE 0x00
#define LMS_SHADOW_AFTERFREE 0x03
#define LMS_SHADOW_REDZONE 0x02
#define LMS_SHADOW_PAINT 0x01
#define LMS_SHADOW_MASK 0x03
#define LMS_SHADOW_BITS_PER_CELL 2
#define LMS_MEM_BYTES_PER_SHADOW_CELL 4
#define LMS_SHADOW_U8_CELL_NUM 4
#define LMS_SHADOW_U8_REFER_BYTES 16
#define LMS_SHADOW_ACCESSABLE_U8 0x00
#define LMS_SHADOW_AFTERFREE_U8 0xFF
#define LMS_SHADOW_REDZONE_U8 0xAA
#define LMS_SHADOW_MASK_U8 0xFF
#define LMS_SHADOW_PAINT_U8 0x55
#define MEM_REGION_SIZE_1 1
#define MEM_REGION_SIZE_2 2
#define MEM_REGION_SIZE_4 4
#define MEM_REGION_SIZE_8 8
#define MEM_REGION_SIZE_16 16
#define LMS_RZ_SIZE 4
#define LMS_OK 0
#define LMS_NOK 1
#define PAGE_ADDR_MASK 0xFFFFE000
#define SHADOW_BASE \
((USPACE_MAP_BASE + (USPACE_MAP_SIZE / (LMS_SHADOW_U8_REFER_BYTES + 1)) * LMS_SHADOW_U8_REFER_BYTES) & \
PAGE_ADDR_MASK)
#define OVERHEAD (2 * sizeof(size_t))
#define LMS_MEM_ALIGN_DOWN(value, align) (((uint32_t)(value)) & ~((uint32_t)((align) - 1)))
#define LMS_MEM_ALIGN_UP(value, align) (((uint32_t)(value) + ((align) - 1)) & ~((uint32_t)((align) - 1)))
typedef struct {
uintptr_t memAddr;
uintptr_t shadowAddr;
uint32_t shadowOffset;
uint32_t shadowValue;
} LmsAddrInfo;
extern pthread_mutex_t g_lmsMutex;
ATTRIBUTE_NO_SANITIZE_ADDRESS static inline void LmsLock(pthread_mutex_t *lock)
{
(void)pthread_mutex_lock(lock);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS static inline int LmsTrylock(pthread_mutex_t *lock)
{
return pthread_mutex_trylock(lock);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS static inline void LmsUnlock(pthread_mutex_t *lock)
{
(void)pthread_mutex_unlock(lock);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS static inline void LmsCrash(void)
{
*(volatile char *)(SHADOW_BASE - 1) = 0;
}
uint32_t LmsIsShadowAddrMapped(uintptr_t sdStartAddr, uintptr_t sdEndAddr);
void LmsSetShadowValue(uintptr_t startAddr, uintptr_t endAddr, char value);
void LmsGetShadowValue(uintptr_t addr, uint32_t *shadowValue);
void LmsReportError(uintptr_t p, size_t size, uint32_t errMod);
void LmsMem2Shadow(uintptr_t memAddr, uintptr_t *shadowAddr, uint32_t *shadowOffset);
void LmsCheckValid(const char *dest, const char *src);
void *__real_malloc(size_t);
void __real_free(void *);
void *__real_calloc(size_t, size_t);
void *__real_realloc(void *, size_t);
void *__real_valloc(size_t);
void *__real_aligned_alloc(size_t, size_t);
void *__real_memcpy(void *__restrict, const void *__restrict, size_t);
void *__real_memmove(void *, const void *, size_t);
char *__real_strcat(char *, const char *);
char *__real_strcpy(char *, const char *);
void *__real_memset(void *, int, size_t);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_store1_noabort(uintptr_t p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_store4_noabort(uintptr_t p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_load4_noabort(uintptr_t p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_load1_noabort(uintptr_t p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_loadN_noabort(uintptr_t p, uint32_t size);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_storeN_noabort(uintptr_t p, uint32_t size);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_store2_noabort(uintptr_t p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_load2_noabort(uintptr_t p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_store8_noabort(uintptr_t p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_load8_noabort(uintptr_t p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_load16_noabort(uintptr_t p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_store16_noabort(uintptr_t p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_handle_no_return(void);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_LMS_PRI_H */
\ No newline at end of file
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "los_lms_pri.h"
ATTRIBUTE_NO_SANITIZE_ADDRESS void LmsFree(void *ptr)
{
if (ptr == NULL) {
return;
}
size_t allocSize = malloc_usable_size(ptr);
uintptr_t shadowAddr, offset;
LmsMem2Shadow((uintptr_t)ptr, &shadowAddr, &offset);
LmsLock(&g_lmsMutex);
if (LmsIsShadowAddrMapped(shadowAddr, shadowAddr) == LMS_OK) {
uint32_t acShadowValue;
LmsGetShadowValue((uintptr_t)ptr, &acShadowValue);
if (acShadowValue != LMS_SHADOW_ACCESSABLE) {
char erroMode = (acShadowValue == LMS_SHADOW_AFTERFREE ? FREE_ERRORMODE : UNKNOWN_ERROR);
LmsReportError((uintptr_t)ptr, MEM_REGION_SIZE_1, erroMode);
goto UNLOCK_OUT;
}
} else {
LMS_OUTPUT_ERROR("Error! Free an unallocated memory:%p!\n", ptr);
goto UNLOCK_OUT;
}
__real_free(ptr);
LmsSetShadowValue((uintptr_t)ptr, (uintptr_t)ptr + allocSize, LMS_SHADOW_AFTERFREE_U8);
UNLOCK_OUT:
LmsUnlock(&g_lmsMutex);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsMalloc(size_t size)
{
void *ptr = __real_malloc(size);
if (ptr == NULL) {
return ptr;
}
return LmsTagMem(ptr, size);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsRealloc(void *ptr, size_t size)
{
void *p = __real_realloc(ptr, size);
if (p == NULL) {
return p;
}
return LmsTagMem(p, size);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsCalloc(size_t m, size_t n)
{
void *p = __real_calloc(m, n);
if (p == NULL) {
return p;
}
return LmsTagMem(p, n * m);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsValloc(size_t size)
{
void *p = __real_valloc(size);
if (p == NULL) {
return p;
}
return LmsTagMem(p, size);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsAlignedAlloc(size_t align, size_t len)
{
void *p = __real_aligned_alloc(align, len);
if (p == NULL) {
return p;
}
return LmsTagMem(p, len);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void *__wrap_aligned_alloc(size_t align, size_t len)
{
return LmsAlignedAlloc(align, len);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void *__wrap_valloc(size_t size)
{
return LmsValloc(size);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void *__wrap_calloc(size_t m, size_t n)
{
return LmsCalloc(m, n);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void *__wrap_realloc(void *p, size_t n)
{
return LmsRealloc(p, n);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void *__wrap_malloc(size_t size)
{
return LmsMalloc(size);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void __wrap_free(void *ptr)
{
return LmsFree(ptr);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsMemset(void *p, int n, size_t size)
{
__asan_storeN_noabort((uintptr_t)p, size);
return __real_memset(p, n, size);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void *__wrap_memset(void *p, int n, size_t size)
{
return LmsMemset(p, n, size);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsMemcpy(void *__restrict dest, const void *__restrict src, size_t size)
{
__asan_loadN_noabort((uintptr_t)src, size);
__asan_storeN_noabort((uintptr_t)dest, size);
return __real_memcpy(dest, src, size);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void *__wrap_memcpy(void *__restrict dest, const void *__restrict src, size_t size)
{
return LmsMemcpy(dest, src, size);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void *LmsMemmove(void *dest, const void *src, size_t len)
{
__asan_loadN_noabort((uintptr_t)src, len);
__asan_storeN_noabort((uintptr_t)dest, len);
return __real_memmove(dest, src, len);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS void *__wrap_memmove(void *dest, const void *src, size_t len)
{
return LmsMemmove(dest, src, len);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS char *LmsStrcat(char *s, const char *append)
{
if ((s == NULL) || (append == NULL)) {
return NULL;
}
char *save = s;
for (; *s != '\0'; ++s) {
}
LmsCheckValid(s, append);
return __real_strcat(save, append);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS char *__wrap_strcat(char *s, const char *append)
{
return LmsStrcat(s, append);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS char *LmsStrcpy(char *dest, const char *src)
{
if ((dest == NULL) || (src == NULL)) {
return NULL;
}
LmsCheckValid(dest, src);
return __real_strcpy(dest, src);
}
ATTRIBUTE_NO_SANITIZE_ADDRESS char *__wrap_strcpy(char *dest, const char *src)
{
return LmsStrcpy(dest, src);
}
\ No newline at end of file
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LOS_LMS_H
#define _LOS_LMS_H
#include "los_typedef.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#ifdef LOSCFG_KERNEL_LMS
UINT32 LOS_LmsCheckPoolAdd(const VOID *pool, UINT32 size);
VOID LOS_LmsCheckPoolDel(const VOID *pool);
VOID LOS_LmsAddrProtect(UINTPTR addrStart, UINTPTR addrEnd);
VOID LOS_LmsAddrDisableProtect(UINTPTR addrStart, UINTPTR addrEnd);
#endif /* LOSCFG_KERNEL_LMS */
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_LMS_H */
\ No newline at end of file
......@@ -63,11 +63,20 @@ kernel_module(module_name) {
]
asmflags = [
"-D__strlen_armv6t2=strlen",
"-D__strcpy_arm=strcpy",
"-D__strcmp_arm=strcmp",
"-D__memcpy_arm=memcpy",
"-D__memchr_arm=memchr",
]
if (defined(LOSCFG_KERNEL_LMS)) {
asmflags += [
"-D__memcpy_arm=__memcpy",
"-D__strcpy_arm=__strcpy",
]
} else {
asmflags += [
"-D__memcpy_arm=memcpy",
"-D__strcpy_arm=strcpy",
]
}
sources += [
"src/arch/arm/memcmp.S",
"src/arch/arm/memset.S",
......
......@@ -37,11 +37,15 @@ LOCAL_SRCS += \
LOCAL_CMACRO = \
-D__strlen_armv6t2=strlen \
-D__strcpy_arm=strcpy \
-D__strcmp_arm=strcmp \
-D__memcpy_arm=memcpy \
-D__memchr_arm=memchr
ifeq ($(LOSCFG_KERNEL_LMS), y)
LOCAL_CMACRO += -D__memcpy_arm=__memcpy -D__strcpy_arm=__strcpy
else
LOCAL_CMACRO += -D__memcpy_arm=memcpy -D__strcpy_arm=strcpy
endif
# Replace the general srcs of the same name with specially optimized srcs
LOCAL_SRCS += $(LOCAL_OPT_SRCS)
LOCAL_SRCS := $(filter-out $(LOCAL_FILTER_SRCS),$(LOCAL_SRCS))
......
......@@ -31,10 +31,18 @@
.syntax unified
.arch armv7-a
.fpu neon
.globl memset @ -- Begin function memset
.p2align 2
.type memset,%function
memset:
#define FUNCTION(x) \
.globl x; \
.p2align 2; \
.type x,%function; \
x:
#if defined(LOSCFG_KERNEL_LMS)
FUNCTION(__memset)
#else
FUNCTION(memset)
#endif
@ r0 = address
@ r1 = char
@ r2 = count
......
......@@ -35,6 +35,22 @@ module_name = get_path_info(rebase_path("."), "name")
kernel_module(module_name) {
sources = libsec_sources
if (defined(LOSCFG_KERNEL_LMS)) {
if (ohos_build_compiler == "gcc") {
cflags_c = [ "-fsanitize=kernel-address" ]
} else {
cflags_c = [
"-fsanitize=kernel-address",
"-mllvm",
"-asan-instrumentation-with-call-threshold=0",
"-mllvm",
"-asan-stack=0",
"-mllvm",
"-asan-globals=0",
]
}
}
public_configs = [ ":public" ]
}
......
......@@ -163,6 +163,12 @@ ifeq ($(LOSCFG_KERNEL_PERF), y)
LITEOS_PERF_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/perf
endif
ifeq ($(LOSCFG_KERNEL_LMS), y)
LITEOS_BASELIB += -llms
LIB_SUBDIRS += kernel/extended/lms
LITEOS_LMS_INCLUDE += -I $(LITEOSTOPDIR)/kernel/extended/lms
endif
ifeq ($(LOSCFG_KERNEL_LITEIPC), y)
LITEOS_BASELIB += -lliteipc
LIB_SUBDIRS += kernel/extended/liteipc
......@@ -507,7 +513,7 @@ LITEOS_EXTKERNEL_INCLUDE := $(LITEOS_CPPSUPPORT_INCLUDE) $(LITEOS_DYNLOAD_INCL
$(LITEOS_TICKLESS_INCLUDE) $(LITEOS_HOOK_INCLUDE)\
$(LITEOS_VDSO_INCLUDE) $(LITEOS_LITEIPC_INCLUDE) \
$(LITEOS_PIPE_INCLUDE) $(LITEOS_CPUP_INCLUDE) \
$(LITEOS_PERF_INCLUDE)
$(LITEOS_PERF_INCLUDE) $(LITEOS_LMS_INCLUDE)
LITEOS_COMPAT_INCLUDE := $(LITEOS_POSIX_INCLUDE) $(LITEOS_LINUX_INCLUDE) \
$(LITEOS_BSD_INCLUDE)
LITEOS_FS_INCLUDE := $(LITEOS_VFS_INCLUDE) $(LITEOS_FAT_CACHE_INCLUDE) \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册