feat: L0~L1 支持Lms
1.【需求描述】: 支持内核态和用户态堆内存非法访问检测,包括:越界访问、double free、释放后使用;支持libc常用高频函数内存检测;支持安全函数内存检测;读写检测可配可裁剪。 2.【方案描述】: L0 ~ L1: (1).影子内存映射与标记 (2).编译器使能-fsanitize=kernel-address 自动插桩检测点 (3).实时校验影子内存的合法性; (4).错误访问打印回溯栈 BREAKING CHANGE: 新增支持API: LOS_LmsCheckPoolAdd使能检测指定内存池 LOS_LmsCheckPoolDel不检测指定内存池 LOS_LmsAddrProtect为指定内存段上锁,不允许访问 LOS_LmsAddrDisableProtect去能指定内存段的访问保护 Close #I4HYAV Signed-off-by: LiteOS2021 <dinglu@huawei.com> Change-Id: Id8e5c890656da9edc4a22227e6a3c32205c024ce
This commit is contained in:
parent
48f645db84
commit
e748fdbe57
|
@ -55,4 +55,8 @@ group("apps") {
|
|||
if (defined(LOSCFG_DRIVERS_PERF)) {
|
||||
deps += [ "perf" ]
|
||||
}
|
||||
|
||||
if (defined(LOSCFG_KERNEL_LMS)) {
|
||||
deps += [ "lms:sample_usr_lms" ]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
# 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" ]
|
||||
}
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* 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");
|
||||
}
|
|
@ -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",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -98,4 +98,7 @@ source "kernel/extended/blackbox/Kconfig"
|
|||
source "kernel/extended/hidumper/Kconfig"
|
||||
|
||||
######################### config options of perf #########################
|
||||
source "kernel/extended/perf/Kconfig"
|
||||
source "kernel/extended/perf/Kconfig"
|
||||
|
||||
######################### config options of lms #########################
|
||||
source "kernel/extended/lms/Kconfig"
|
|
@ -0,0 +1,43 @@
|
|||
# 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 = [ "." ]
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
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
|
|
@ -0,0 +1,10 @@
|
|||
include $(LITEOSTOPDIR)/config.mk
|
||||
|
||||
MODULE_NAME := $(notdir $(shell pwd))
|
||||
|
||||
LOCAL_SRCS := $(wildcard *.c)
|
||||
|
||||
LOCAL_FLAGS := $(LOCAL_INCLUDE)
|
||||
|
||||
include $(MODULE)
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,769 @@
|
|||
/*
|
||||
* 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"
|
||||
#include "los_spinlock.h"
|
||||
#include "los_exc.h"
|
||||
#include "los_sched_pri.h"
|
||||
#include "los_atomic.h"
|
||||
#include "los_init.h"
|
||||
|
||||
LITE_OS_SEC_BSS STATIC LmsMemListNode g_lmsCheckPoolArray[LOSCFG_LMS_MAX_RECORD_POOL_NUM];
|
||||
LITE_OS_SEC_BSS STATIC LOS_DL_LIST g_lmsCheckPoolList;
|
||||
STATIC Atomic g_checkDepth = 0;
|
||||
LmsHook *g_lms = NULL;
|
||||
|
||||
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_lmsSpin);
|
||||
#define LMS_LOCK(state) LOS_SpinLockSave(&g_lmsSpin, &(state))
|
||||
#define LMS_UNLOCK(state) LOS_SpinUnlockRestore(&g_lmsSpin, (state))
|
||||
|
||||
#define OS_MEM_ALIGN_BACK(value, align) (((UINT32)(value)) & ~((UINT32)((align) - 1)))
|
||||
#define OS_MEM_ALIGN_SIZE sizeof(UINTPTR)
|
||||
#define POOL_ADDR_ALIGNSIZE 64
|
||||
#define LMS_POOL_UNUSED 0
|
||||
#define LMS_POOL_USED 1
|
||||
#define INVALID_SHADOW_VALUE 0xFFFFFFFF
|
||||
|
||||
STATIC UINT32 OsLmsPoolResize(UINT32 size)
|
||||
{
|
||||
return OS_MEM_ALIGN_BACK(LMS_POOL_RESIZE(size), POOL_ADDR_ALIGNSIZE);
|
||||
}
|
||||
|
||||
STATIC LmsMemListNode *OsLmsGetPoolNode(const VOID *pool)
|
||||
{
|
||||
UINTPTR poolAddr = (UINTPTR)pool;
|
||||
LmsMemListNode *current = NULL;
|
||||
LOS_DL_LIST *listHead = &g_lmsCheckPoolList;
|
||||
|
||||
if (LOS_ListEmpty(&g_lmsCheckPoolList)) {
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(current, listHead, LmsMemListNode, node) {
|
||||
if (current->poolAddr == poolAddr) {
|
||||
return current;
|
||||
}
|
||||
}
|
||||
|
||||
EXIT:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC LmsMemListNode *OsLmsGetPoolNodeFromAddr(UINTPTR addr)
|
||||
{
|
||||
LmsMemListNode *current = NULL;
|
||||
LOS_DL_LIST *listHead = &g_lmsCheckPoolList;
|
||||
|
||||
if (LOS_ListEmpty(&g_lmsCheckPoolList)) {
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(current, listHead, LmsMemListNode, node) {
|
||||
if ((addr >= current->poolAddr) && (addr < current->poolAddr + current->poolSize)) {
|
||||
return current;
|
||||
}
|
||||
}
|
||||
|
||||
EXIT:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC LmsMemListNode *OsLmsCheckPoolCreate(VOID)
|
||||
{
|
||||
UINT32 i;
|
||||
LmsMemListNode *current = NULL;
|
||||
for (i = 0; i < LOSCFG_LMS_MAX_RECORD_POOL_NUM; i++) {
|
||||
current = &g_lmsCheckPoolArray[i];
|
||||
if (current->used == LMS_POOL_UNUSED) {
|
||||
current->used = LMS_POOL_USED;
|
||||
return current;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
UINT32 LOS_LmsCheckPoolAdd(const VOID *pool, UINT32 size)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINTPTR poolAddr = (UINTPTR)pool;
|
||||
UINT32 realSize;
|
||||
LmsMemListNode *lmsPoolNode = NULL;
|
||||
|
||||
if (pool == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LMS_LOCK(intSave);
|
||||
|
||||
lmsPoolNode = OsLmsGetPoolNodeFromAddr((UINTPTR)pool);
|
||||
if (lmsPoolNode != NULL) { /* if pool range already on checklist */
|
||||
if (lmsPoolNode->poolAddr != (UINTPTR)pool) { /* pool is a subset of lmsPoolNode->poolAddr */
|
||||
/* do not add it again, just return */
|
||||
PRINT_DEBUG("[LMS]pool %p already on lms checklist !\n", pool);
|
||||
LMS_UNLOCK(intSave);
|
||||
return size; /* return size indicate the shadow memory init successful */
|
||||
} else { /* Re-initialize the same pool, maybe with different size */
|
||||
/* delete the old node, then add a new one */
|
||||
lmsPoolNode->used = LMS_POOL_UNUSED;
|
||||
LOS_ListDelete(&(lmsPoolNode->node));
|
||||
}
|
||||
}
|
||||
|
||||
lmsPoolNode = OsLmsCheckPoolCreate();
|
||||
if (lmsPoolNode == NULL) {
|
||||
PRINT_DEBUG("[LMS]the num of lms check pool is max already !\n");
|
||||
LMS_UNLOCK(intSave);
|
||||
return 0;
|
||||
}
|
||||
realSize = OsLmsPoolResize(size);
|
||||
|
||||
lmsPoolNode->poolAddr = poolAddr;
|
||||
lmsPoolNode->poolSize = realSize;
|
||||
lmsPoolNode->shadowStart = (UINTPTR)poolAddr + realSize;
|
||||
lmsPoolNode->shadowSize = poolAddr + size - lmsPoolNode->shadowStart;
|
||||
/* init shadow value */
|
||||
(VOID)memset((VOID *)lmsPoolNode->shadowStart, LMS_SHADOW_AFTERFREE_U8, lmsPoolNode->shadowSize);
|
||||
|
||||
LOS_ListAdd(&g_lmsCheckPoolList, &(lmsPoolNode->node));
|
||||
|
||||
LMS_UNLOCK(intSave);
|
||||
return realSize;
|
||||
}
|
||||
|
||||
VOID LOS_LmsCheckPoolDel(const VOID *pool)
|
||||
{
|
||||
UINT32 intSave;
|
||||
if (pool == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
LMS_LOCK(intSave);
|
||||
LmsMemListNode *delNode = OsLmsGetPoolNode(pool);
|
||||
if (delNode == NULL) {
|
||||
PRINT_ERR("[LMS]pool %p is not on lms checklist !\n", pool);
|
||||
goto Release;
|
||||
}
|
||||
delNode->used = LMS_POOL_UNUSED;
|
||||
LOS_ListDelete(&(delNode->node));
|
||||
Release:
|
||||
LMS_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
STATIC UINT32 OsLmsInit(VOID)
|
||||
{
|
||||
(VOID)memset(g_lmsCheckPoolArray, 0, sizeof(g_lmsCheckPoolArray));
|
||||
LOS_ListInit(&g_lmsCheckPoolList);
|
||||
static LmsHook hook = {
|
||||
.init = LOS_LmsCheckPoolAdd,
|
||||
.mallocMark = OsLmsLosMallocMark,
|
||||
.freeMark = OsLmsLosFreeMark,
|
||||
.simpleMark = OsLmsSimpleMark,
|
||||
.check = OsLmsCheckValid,
|
||||
};
|
||||
g_lms = &hook;
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC INLINE UINT32 OsLmsMem2Shadow(LmsMemListNode *node, UINTPTR memAddr, UINTPTR *shadowAddr, UINT32 *shadowOffset)
|
||||
{
|
||||
if ((memAddr < node->poolAddr) || (memAddr >= node->poolAddr + node->poolSize)) { /* check ptr valid */
|
||||
PRINT_ERR("[LMS]memAddr %p is not in pool region [%p, %p)\n", memAddr, node->poolAddr,
|
||||
node->poolAddr + node->poolSize);
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
UINT32 memOffset = memAddr - node->poolAddr;
|
||||
*shadowAddr = node->shadowStart + memOffset / LMS_SHADOW_U8_REFER_BYTES;
|
||||
*shadowOffset = ((memOffset % LMS_SHADOW_U8_REFER_BYTES) / LMS_SHADOW_U8_CELL_NUM) *
|
||||
LMS_SHADOW_BITS_PER_CELL; /* (memOffset % 16) / 4 */
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsLmsGetShadowInfo(LmsMemListNode *node, UINTPTR memAddr, LmsAddrInfo *info)
|
||||
{
|
||||
UINTPTR shadowAddr;
|
||||
UINT32 shadowOffset;
|
||||
UINT32 shadowValue;
|
||||
|
||||
if (OsLmsMem2Shadow(node, memAddr, &shadowAddr, &shadowOffset) != LOS_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
shadowValue = ((*(UINT8 *)shadowAddr) >> shadowOffset) & LMS_SHADOW_MASK;
|
||||
info->memAddr = memAddr;
|
||||
info->shadowAddr = shadowAddr;
|
||||
info->shadowOffset = shadowOffset;
|
||||
info->shadowValue = shadowValue;
|
||||
}
|
||||
|
||||
VOID OsLmsSetShadowValue(LmsMemListNode *node, UINTPTR startAddr, UINTPTR endAddr, UINT8 value)
|
||||
{
|
||||
UINTPTR shadowStart;
|
||||
UINTPTR shadowEnd;
|
||||
UINT32 startOffset;
|
||||
UINT32 endOffset;
|
||||
|
||||
UINT8 shadowValueMask;
|
||||
UINT8 shadowValue;
|
||||
|
||||
/* endAddr -1, then we mark [startAddr, endAddr) to value */
|
||||
if (OsLmsMem2Shadow(node, startAddr, &shadowStart, &startOffset) ||
|
||||
OsLmsMem2Shadow(node, endAddr - 1, &shadowEnd, &endOffset)) {
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
*(UINT8 *)shadowStart &= ~shadowValueMask;
|
||||
*(UINT8 *)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;
|
||||
*(UINT8 *)shadowStart &= ~shadowValueMask;
|
||||
*(UINT8 *)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;
|
||||
*(UINT8 *)shadowEnd &= ~shadowValueMask;
|
||||
*(UINT8 *)shadowEnd |= shadowValue;
|
||||
shadowEnd -= 1;
|
||||
}
|
||||
|
||||
if (shadowEnd + 1 > shadowStart) {
|
||||
(VOID)memset((VOID *)shadowStart, value & LMS_SHADOW_MASK_U8, shadowEnd + 1 - shadowStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsLmsGetShadowValue(LmsMemListNode *node, UINTPTR addr, UINT32 *shadowValue)
|
||||
{
|
||||
UINTPTR shadowAddr;
|
||||
UINT32 shadowOffset;
|
||||
if (OsLmsMem2Shadow(node, addr, &shadowAddr, &shadowOffset) != LOS_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
*shadowValue = ((*(UINT8 *)shadowAddr) >> shadowOffset) & LMS_SHADOW_MASK;
|
||||
}
|
||||
|
||||
VOID OsLmsSimpleMark(UINTPTR startAddr, UINTPTR endAddr, UINT32 value)
|
||||
{
|
||||
UINT32 intSave;
|
||||
if (endAddr <= startAddr) {
|
||||
PRINT_DEBUG("[LMS]mark 0x%x, 0x%x, 0x%x\n", startAddr, endAddr, (UINTPTR)__builtin_return_address(0));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IS_ALIGNED(startAddr, OS_MEM_ALIGN_SIZE) || !IS_ALIGNED(endAddr, OS_MEM_ALIGN_SIZE)) {
|
||||
PRINT_ERR("[LMS]mark addr is not aligned! 0x%x, 0x%x\n", startAddr, endAddr);
|
||||
return;
|
||||
}
|
||||
|
||||
LMS_LOCK(intSave);
|
||||
|
||||
LmsMemListNode *node = OsLmsGetPoolNodeFromAddr(startAddr);
|
||||
if (node == NULL) {
|
||||
LMS_UNLOCK(intSave);
|
||||
return;
|
||||
}
|
||||
|
||||
OsLmsSetShadowValue(node, startAddr, endAddr, value);
|
||||
LMS_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
VOID OsLmsLosMallocMark(const VOID *curNodeStart, const VOID *nextNodeStart, UINT32 nodeHeadSize)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINTPTR curNodeStartAddr = (UINTPTR)curNodeStart;
|
||||
UINTPTR nextNodeStartAddr = (UINTPTR)nextNodeStart;
|
||||
|
||||
LMS_LOCK(intSave);
|
||||
LmsMemListNode *node = OsLmsGetPoolNodeFromAddr((UINTPTR)curNodeStart);
|
||||
if (node == NULL) {
|
||||
LMS_UNLOCK(intSave);
|
||||
return;
|
||||
}
|
||||
|
||||
OsLmsSetShadowValue(node, curNodeStartAddr, curNodeStartAddr + nodeHeadSize, LMS_SHADOW_REDZONE_U8);
|
||||
OsLmsSetShadowValue(node, curNodeStartAddr + nodeHeadSize, nextNodeStartAddr, LMS_SHADOW_ACCESSABLE_U8);
|
||||
OsLmsSetShadowValue(node, nextNodeStartAddr, nextNodeStartAddr + nodeHeadSize, LMS_SHADOW_REDZONE_U8);
|
||||
LMS_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
VOID OsLmsCheckValid(UINTPTR checkAddr, BOOL isFreeCheck)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT32 shadowValue = INVALID_SHADOW_VALUE;
|
||||
LMS_LOCK(intSave);
|
||||
LmsMemListNode *node = OsLmsGetPoolNodeFromAddr(checkAddr);
|
||||
if (node == NULL) {
|
||||
LMS_UNLOCK(intSave);
|
||||
return;
|
||||
}
|
||||
|
||||
OsLmsGetShadowValue(node, checkAddr, &shadowValue);
|
||||
LMS_UNLOCK(intSave);
|
||||
if ((shadowValue == LMS_SHADOW_ACCESSABLE) || ((isFreeCheck) && (shadowValue == LMS_SHADOW_PAINT))) {
|
||||
return;
|
||||
}
|
||||
|
||||
OsLmsReportError(checkAddr, MEM_REGION_SIZE_1, isFreeCheck ? FREE_ERRORMODE : COMMON_ERRMODE);
|
||||
}
|
||||
|
||||
VOID OsLmsLosFreeMark(const VOID *curNodeStart, const VOID *nextNodeStart, UINT32 nodeHeadSize)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT32 shadowValue = INVALID_SHADOW_VALUE;
|
||||
|
||||
LMS_LOCK(intSave);
|
||||
LmsMemListNode *node = OsLmsGetPoolNodeFromAddr((UINTPTR)curNodeStart);
|
||||
if (node == NULL) {
|
||||
LMS_UNLOCK(intSave);
|
||||
return;
|
||||
}
|
||||
|
||||
UINTPTR curNodeStartAddr = (UINTPTR)curNodeStart;
|
||||
UINTPTR nextNodeStartAddr = (UINTPTR)nextNodeStart;
|
||||
|
||||
OsLmsGetShadowValue(node, curNodeStartAddr + nodeHeadSize, &shadowValue);
|
||||
if ((shadowValue != LMS_SHADOW_ACCESSABLE) && (shadowValue != LMS_SHADOW_PAINT)) {
|
||||
LMS_UNLOCK(intSave);
|
||||
OsLmsReportError(curNodeStartAddr + nodeHeadSize, MEM_REGION_SIZE_1, FREE_ERRORMODE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (*((UINT8 *)curNodeStart) == 0) { /* if merge the node has memset with 0 */
|
||||
OsLmsSetShadowValue(node, curNodeStartAddr, curNodeStartAddr + nodeHeadSize, LMS_SHADOW_AFTERFREE_U8);
|
||||
}
|
||||
OsLmsSetShadowValue(node, curNodeStartAddr + nodeHeadSize, nextNodeStartAddr, LMS_SHADOW_AFTERFREE_U8);
|
||||
|
||||
if (*((UINT8 *)nextNodeStart) == 0) { /* if merge the node has memset with 0 */
|
||||
OsLmsSetShadowValue(node, nextNodeStartAddr, nextNodeStartAddr + nodeHeadSize, LMS_SHADOW_AFTERFREE_U8);
|
||||
}
|
||||
|
||||
LMS_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
VOID LOS_LmsAddrProtect(UINTPTR addrStart, UINTPTR addrEnd)
|
||||
{
|
||||
UINT32 intSave;
|
||||
if (addrEnd <= addrStart) {
|
||||
return;
|
||||
}
|
||||
LMS_LOCK(intSave);
|
||||
LmsMemListNode *node = OsLmsGetPoolNodeFromAddr(addrStart);
|
||||
if (node != NULL) {
|
||||
OsLmsSetShadowValue(node, addrStart, addrEnd, LMS_SHADOW_REDZONE_U8);
|
||||
}
|
||||
LMS_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
VOID LOS_LmsAddrDisableProtect(UINTPTR addrStart, UINTPTR addrEnd)
|
||||
{
|
||||
UINT32 intSave;
|
||||
if (addrEnd <= addrStart) {
|
||||
return;
|
||||
}
|
||||
LMS_LOCK(intSave);
|
||||
LmsMemListNode *node = OsLmsGetPoolNodeFromAddr(addrStart);
|
||||
if (node != NULL) {
|
||||
OsLmsSetShadowValue(node, addrStart, addrEnd, LMS_SHADOW_ACCESSABLE_U8);
|
||||
}
|
||||
LMS_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
STATIC UINT32 OsLmsCheckAddr(UINTPTR addr)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT32 shadowValue = INVALID_SHADOW_VALUE;
|
||||
/* do not check nested or before all cpu start */
|
||||
if ((LOS_AtomicRead(&g_checkDepth)) || (!OS_SCHEDULER_ALL_ACTIVE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LMS_LOCK(intSave);
|
||||
LmsMemListNode *node = OsLmsGetPoolNodeFromAddr(addr);
|
||||
if (node == NULL) {
|
||||
LMS_UNLOCK(intSave);
|
||||
return LMS_SHADOW_ACCESSABLE_U8;
|
||||
}
|
||||
|
||||
OsLmsGetShadowValue(node, addr, &shadowValue);
|
||||
LMS_UNLOCK(intSave);
|
||||
return shadowValue;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_LMS_CHECK_STRICT
|
||||
STATIC INLINE UINT32 OsLmsCheckAddrRegion(UINTPTR addr, UINT32 size)
|
||||
{
|
||||
UINT32 i;
|
||||
for (i = 0; i < size; i++) {
|
||||
if (OsLmsCheckAddr(addr + i)) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
#else
|
||||
STATIC INLINE UINT32 OsLmsCheckAddrRegion(UINTPTR addr, UINT32 size)
|
||||
{
|
||||
if (OsLmsCheckAddr(addr) || OsLmsCheckAddr(addr + size - 1)) {
|
||||
return LOS_NOK;
|
||||
} else {
|
||||
return LOS_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
VOID OsLmsPrintPoolListInfo(VOID)
|
||||
{
|
||||
UINT32 count = 0;
|
||||
UINT32 intSave;
|
||||
LmsMemListNode *current = NULL;
|
||||
LOS_DL_LIST *listHead = &g_lmsCheckPoolList;
|
||||
|
||||
LMS_LOCK(intSave);
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(current, listHead, LmsMemListNode, node)
|
||||
{
|
||||
count++;
|
||||
PRINT_DEBUG(
|
||||
"[LMS]memory pool[%1u]: totalsize 0x%-8x memstart 0x%-8x memstop 0x%-8x memsize 0x%-8x shadowstart 0x%-8x "
|
||||
"shadowSize 0x%-8x\n",
|
||||
count, current->poolSize + current->shadowSize, current->poolAddr, current->poolAddr + current->poolSize,
|
||||
current->poolSize, current->shadowStart, current->shadowSize);
|
||||
}
|
||||
|
||||
LMS_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
VOID OsLmsPrintMemInfo(UINTPTR addr)
|
||||
{
|
||||
#define LMS_DUMP_OFFSET 16
|
||||
#define LMS_DUMP_RANGE_DOUBLE 2
|
||||
|
||||
PRINTK("\n[LMS] Dump info around address [0x%8x]:\n", addr);
|
||||
const UINT32 printY = LMS_DUMP_OFFSET * LMS_DUMP_RANGE_DOUBLE + 1;
|
||||
const UINT32 printX = LMS_MEM_BYTES_PER_SHADOW_CELL * LMS_DUMP_RANGE_DOUBLE;
|
||||
UINTPTR dumpAddr = addr - addr % printX - LMS_DUMP_OFFSET * printX;
|
||||
UINT32 shadowValue = 0;
|
||||
UINTPTR shadowAddr = 0;
|
||||
UINT32 shadowOffset = 0;
|
||||
LmsMemListNode *nodeInfo = NULL;
|
||||
INT32 isCheckAddr, x, y;
|
||||
|
||||
nodeInfo = OsLmsGetPoolNodeFromAddr(addr);
|
||||
if (nodeInfo == NULL) {
|
||||
PRINT_ERR("[LMS]addr is not in checkpool\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (y = 0; y < printY; y++, dumpAddr += printX) {
|
||||
if (dumpAddr < nodeInfo->poolAddr) { /* find util dumpAddr in pool region */
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((dumpAddr + printX) >=
|
||||
nodeInfo->poolAddr + nodeInfo->poolSize) { /* finish if dumpAddr exceeds pool's upper region */
|
||||
goto END;
|
||||
}
|
||||
|
||||
PRINTK("\n\t[0x%x]: ", dumpAddr);
|
||||
for (x = 0; x < printX; x++) {
|
||||
if ((dumpAddr + x) == addr) {
|
||||
PRINTK("[%02x]", *(UINT8 *)(dumpAddr + x));
|
||||
} else {
|
||||
PRINTK(" %02x ", *(UINT8 *)(dumpAddr + x));
|
||||
}
|
||||
}
|
||||
|
||||
if (OsLmsMem2Shadow(nodeInfo, dumpAddr, &shadowAddr, &shadowOffset) != LOS_OK) {
|
||||
goto END;
|
||||
}
|
||||
|
||||
PRINTK("|\t[0x%x | %2u]: ", shadowAddr, shadowOffset);
|
||||
|
||||
for (x = 0; x < printX; x += LMS_MEM_BYTES_PER_SHADOW_CELL) {
|
||||
OsLmsGetShadowValue(nodeInfo, dumpAddr + x, &shadowValue);
|
||||
isCheckAddr = dumpAddr + x - (UINTPTR)addr + LMS_MEM_BYTES_PER_SHADOW_CELL;
|
||||
if ((isCheckAddr > 0) && (isCheckAddr <= LMS_MEM_BYTES_PER_SHADOW_CELL)) {
|
||||
PRINTK("[%1x]", shadowValue);
|
||||
} else {
|
||||
PRINTK(" %1x ", shadowValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
END:
|
||||
PRINTK("\n");
|
||||
}
|
||||
|
||||
STATIC VOID OsLmsGetErrorInfo(UINTPTR addr, UINT32 size, LmsAddrInfo *info)
|
||||
{
|
||||
LmsMemListNode *node = OsLmsGetPoolNodeFromAddr(addr);
|
||||
OsLmsGetShadowInfo(node, addr, info);
|
||||
if (info->shadowValue != LMS_SHADOW_ACCESSABLE_U8) {
|
||||
return;
|
||||
} else {
|
||||
OsLmsGetShadowInfo(node, addr + size - 1, info);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC VOID OsLmsPrintErrInfo(LmsAddrInfo *info, UINT32 errMod)
|
||||
{
|
||||
switch (info->shadowValue) {
|
||||
case LMS_SHADOW_AFTERFREE:
|
||||
PRINT_ERR("Use after free error detected\n");
|
||||
break;
|
||||
case LMS_SHADOW_REDZONE:
|
||||
PRINT_ERR("Heap buffer overflow error detected\n");
|
||||
break;
|
||||
case LMS_SHADOW_ACCESSABLE:
|
||||
PRINT_ERR("No error\n");
|
||||
break;
|
||||
default:
|
||||
PRINT_ERR("UnKnown Error detected\n");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (errMod) {
|
||||
case FREE_ERRORMODE:
|
||||
PRINT_ERR("Illegal Double free address at: [0x%lx]\n", info->memAddr);
|
||||
break;
|
||||
case LOAD_ERRMODE:
|
||||
PRINT_ERR("Illegal READ address at: [0x%lx]\n", info->memAddr);
|
||||
break;
|
||||
case STORE_ERRMODE:
|
||||
PRINT_ERR("Illegal WRITE address at: [0x%lx]\n", info->memAddr);
|
||||
break;
|
||||
case COMMON_ERRMODE:
|
||||
PRINT_ERR("Common Error at: [0x%lx]\n", info->memAddr);
|
||||
break;
|
||||
default:
|
||||
PRINT_ERR("UnKnown Error mode at: [0x%lx]\n", info->memAddr);
|
||||
break;
|
||||
}
|
||||
|
||||
PRINT_ERR("Shadow memory address: [0x%lx : %1u] Shadow memory value: [%u] \n", info->shadowAddr,
|
||||
info->shadowOffset, info->shadowValue);
|
||||
}
|
||||
|
||||
VOID OsLmsReportError(UINTPTR p, UINT32 size, UINT32 errMod)
|
||||
{
|
||||
UINT32 intSave;
|
||||
LmsAddrInfo info;
|
||||
|
||||
(VOID)LOS_AtomicAdd(&g_checkDepth, 1);
|
||||
LMS_LOCK(intSave);
|
||||
(VOID)memset(&info, 0, sizeof(LmsAddrInfo));
|
||||
|
||||
PRINT_ERR("***** Kernel Address Sanitizer Error Detected Start *****\n");
|
||||
|
||||
OsLmsGetErrorInfo(p, size, &info);
|
||||
|
||||
OsLmsPrintErrInfo(&info, errMod);
|
||||
|
||||
OsBackTrace();
|
||||
|
||||
OsLmsPrintMemInfo(info.memAddr);
|
||||
LMS_UNLOCK(intSave);
|
||||
PRINT_ERR("***** Kernel Address Sanitizer Error Detected End *****\n");
|
||||
(VOID)LOS_AtomicSub(&g_checkDepth, 1);
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_LMS_STORE_CHECK
|
||||
VOID __asan_store1_noabort(UINTPTR p)
|
||||
{
|
||||
if (OsLmsCheckAddr(p) != LMS_SHADOW_ACCESSABLE_U8) {
|
||||
OsLmsReportError(p, MEM_REGION_SIZE_1, STORE_ERRMODE);
|
||||
}
|
||||
}
|
||||
|
||||
VOID __asan_store2_noabort(UINTPTR p)
|
||||
{
|
||||
if (OsLmsCheckAddrRegion(p, MEM_REGION_SIZE_2) != LOS_OK) {
|
||||
OsLmsReportError(p, MEM_REGION_SIZE_2, STORE_ERRMODE);
|
||||
}
|
||||
}
|
||||
|
||||
VOID __asan_store4_noabort(UINTPTR p)
|
||||
{
|
||||
if (OsLmsCheckAddrRegion(p, MEM_REGION_SIZE_4) != LOS_OK) {
|
||||
OsLmsReportError(p, MEM_REGION_SIZE_4, STORE_ERRMODE);
|
||||
}
|
||||
}
|
||||
|
||||
VOID __asan_store8_noabort(UINTPTR p)
|
||||
{
|
||||
if (OsLmsCheckAddrRegion(p, MEM_REGION_SIZE_8) != LOS_OK) {
|
||||
OsLmsReportError(p, MEM_REGION_SIZE_8, STORE_ERRMODE);
|
||||
}
|
||||
}
|
||||
|
||||
VOID __asan_store16_noabort(UINTPTR p)
|
||||
{
|
||||
if (OsLmsCheckAddrRegion(p, MEM_REGION_SIZE_16) != LOS_OK) {
|
||||
OsLmsReportError(p, MEM_REGION_SIZE_16, STORE_ERRMODE);
|
||||
}
|
||||
}
|
||||
|
||||
VOID __asan_storeN_noabort(UINTPTR p, UINT32 size)
|
||||
{
|
||||
if (OsLmsCheckAddrRegion(p, size) != LOS_OK) {
|
||||
OsLmsReportError(p, size, STORE_ERRMODE);
|
||||
}
|
||||
}
|
||||
#else
|
||||
VOID __asan_store1_noabort(UINTPTR p)
|
||||
{
|
||||
(VOID)p;
|
||||
}
|
||||
|
||||
VOID __asan_store2_noabort(UINTPTR p)
|
||||
{
|
||||
(VOID)p;
|
||||
}
|
||||
|
||||
VOID __asan_store4_noabort(UINTPTR p)
|
||||
{
|
||||
(VOID)p;
|
||||
}
|
||||
|
||||
VOID __asan_store8_noabort(UINTPTR p)
|
||||
{
|
||||
(VOID)p;
|
||||
}
|
||||
|
||||
VOID __asan_store16_noabort(UINTPTR p)
|
||||
{
|
||||
(VOID)p;
|
||||
}
|
||||
|
||||
VOID __asan_storeN_noabort(UINTPTR p, UINT32 size)
|
||||
{
|
||||
(VOID)p;
|
||||
(VOID)size;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_LMS_LOAD_CHECK
|
||||
VOID __asan_load1_noabort(UINTPTR p)
|
||||
{
|
||||
if (OsLmsCheckAddr(p) != LMS_SHADOW_ACCESSABLE_U8) {
|
||||
OsLmsReportError(p, MEM_REGION_SIZE_1, LOAD_ERRMODE);
|
||||
}
|
||||
}
|
||||
|
||||
VOID __asan_load2_noabort(UINTPTR p)
|
||||
{
|
||||
if (OsLmsCheckAddrRegion(p, MEM_REGION_SIZE_2) != LOS_OK) {
|
||||
OsLmsReportError(p, MEM_REGION_SIZE_2, LOAD_ERRMODE);
|
||||
}
|
||||
}
|
||||
|
||||
VOID __asan_load4_noabort(UINTPTR p)
|
||||
{
|
||||
if (OsLmsCheckAddrRegion(p, MEM_REGION_SIZE_4) != LOS_OK) {
|
||||
OsLmsReportError(p, MEM_REGION_SIZE_4, LOAD_ERRMODE);
|
||||
}
|
||||
}
|
||||
|
||||
VOID __asan_load8_noabort(UINTPTR p)
|
||||
{
|
||||
if (OsLmsCheckAddrRegion(p, MEM_REGION_SIZE_8) != LOS_OK) {
|
||||
OsLmsReportError(p, MEM_REGION_SIZE_8, LOAD_ERRMODE);
|
||||
}
|
||||
}
|
||||
|
||||
VOID __asan_load16_noabort(UINTPTR p)
|
||||
{
|
||||
if (OsLmsCheckAddrRegion(p, MEM_REGION_SIZE_16) != LOS_OK) {
|
||||
OsLmsReportError(p, MEM_REGION_SIZE_16, LOAD_ERRMODE);
|
||||
}
|
||||
}
|
||||
|
||||
VOID __asan_loadN_noabort(UINTPTR p, UINT32 size)
|
||||
{
|
||||
if (OsLmsCheckAddrRegion(p, size) != LOS_OK) {
|
||||
OsLmsReportError(p, size, LOAD_ERRMODE);
|
||||
}
|
||||
}
|
||||
#else
|
||||
VOID __asan_load1_noabort(UINTPTR p)
|
||||
{
|
||||
(VOID)p;
|
||||
}
|
||||
|
||||
VOID __asan_load2_noabort(UINTPTR p)
|
||||
{
|
||||
(VOID)p;
|
||||
}
|
||||
|
||||
VOID __asan_load4_noabort(UINTPTR p)
|
||||
{
|
||||
(VOID)p;
|
||||
}
|
||||
|
||||
VOID __asan_load8_noabort(UINTPTR p)
|
||||
{
|
||||
(VOID)p;
|
||||
}
|
||||
|
||||
VOID __asan_load16_noabort(UINTPTR p)
|
||||
{
|
||||
(VOID)p;
|
||||
}
|
||||
|
||||
VOID __asan_loadN_noabort(UINTPTR p, UINT32 size)
|
||||
{
|
||||
(VOID)p;
|
||||
(VOID)size;
|
||||
}
|
||||
#endif
|
||||
VOID __asan_handle_no_return(VOID)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LOS_MODULE_INIT(OsLmsInit, LOS_INIT_LEVEL_KMOD_PREVM);
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* 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 */
|
|
@ -0,0 +1,59 @@
|
|||
# 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
|
||||
}
|
|
@ -0,0 +1,486 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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 */
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* 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 */
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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 */
|
|
@ -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) \
|
||||
|
|
Loading…
Reference in New Issue