You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gu...@apache.org on 2021/11/02 16:32:57 UTC
[incubator-nuttx] 02/03: mm: Support the kernel address sanitizer
This is an automated email from the ASF dual-hosted git repository.
gustavonihei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 39cdd99d77137e1c92859cf8dd7a2675690cc1d6
Author: chenwei23 <ch...@xiaomi.com>
AuthorDate: Sat Oct 9 15:22:28 2021 +0800
mm: Support the kernel address sanitizer
Signed-off-by: chenwei23 <ch...@xiaomi.com>
---
mm/Kconfig | 8 +
mm/Makefile | 1 +
mm/kasan/Make.defs | 34 ++++
mm/kasan/kasan.c | 409 +++++++++++++++++++++++++++++++++++++++++++
mm/kasan/kasan.h | 115 ++++++++++++
mm/mm_heap/mm_free.c | 5 +
mm/mm_heap/mm_initialize.c | 5 +
mm/mm_heap/mm_malloc.c | 20 +--
mm/mm_heap/mm_memalign.c | 7 +
mm/mm_heap/mm_realloc.c | 19 +-
mm/umm_heap/umm_initialize.c | 13 +-
tools/nxstyle.c | 9 +
12 files changed, 625 insertions(+), 20 deletions(-)
diff --git a/mm/Kconfig b/mm/Kconfig
index 8c5e772..8746a20 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -178,4 +178,12 @@ config MM_CIRCBUF
---help---
Build in support for the circular buffer management.
+config MM_KASAN
+ bool "Kernel Address Sanitizer"
+ default n
+ ---help---
+ KASan is a fast compiler-based tool for detecting memory
+ bugs in native code. After turn on this option, Please
+ add -fsanitize=kernel-address to CFLAGS/CXXFLAGS too.
+
source "mm/iob/Kconfig"
diff --git a/mm/Makefile b/mm/Makefile
index 0398029..323a8ed 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -29,6 +29,7 @@ include mm_gran/Make.defs
include shm/Make.defs
include iob/Make.defs
include circbuf/Make.defs
+include kasan/Make.defs
BINDIR ?= bin
diff --git a/mm/kasan/Make.defs b/mm/kasan/Make.defs
new file mode 100644
index 0000000..ab67a9c
--- /dev/null
+++ b/mm/kasan/Make.defs
@@ -0,0 +1,34 @@
+############################################################################
+# mm/kasan/Make.defs
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership. The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+ifeq ($(CONFIG_MM_KASAN),y)
+
+CSRCS += kasan.c
+
+# Disable kernel-address in mm subsystem
+
+CFLAGS += -fno-sanitize=kernel-address
+
+# Add the core heap directory to the build
+
+DEPPATH += --dep-path kasan
+VPATH += :kasan
+
+endif
diff --git a/mm/kasan/kasan.c b/mm/kasan/kasan.c
new file mode 100644
index 0000000..90c324e
--- /dev/null
+++ b/mm/kasan/kasan.c
@@ -0,0 +1,409 @@
+/****************************************************************************
+ * mm/kasan/kasan.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/semaphore.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "kasan.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define KASAN_BYTES_PER_WORD (sizeof(uintptr_t))
+#define KASAN_BITS_PER_WORD (KASAN_BYTES_PER_WORD * 8)
+
+#define KASAN_FIRST_WORD_MASK(start) \
+ (UINTPTR_MAX << ((start) & (KASAN_BITS_PER_WORD - 1)))
+#define KASAN_LAST_WORD_MASK(end) \
+ (UINTPTR_MAX >> (-(end) & (KASAN_BITS_PER_WORD - 1)))
+
+#define KASAN_SHADOW_SCALE (sizeof(uintptr_t))
+
+#define KASAN_SHADOW_SIZE(size) \
+ (KASAN_BYTES_PER_WORD * ((size) / KASAN_SHADOW_SCALE / KASAN_BITS_PER_WORD))
+#define KASAN_REGION_SIZE(size) \
+ (sizeof(struct kasan_region_s) + KASAN_SHADOW_SIZE(size))
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct kasan_region_s
+{
+ FAR struct kasan_region_s *next;
+ uintptr_t begin;
+ uintptr_t end;
+ uintptr_t shadow[1];
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static sem_t g_lock = SEM_INITIALIZER(1);
+static FAR struct kasan_region_s *g_region;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static FAR uintptr_t *kasan_mem_to_shadow(uintptr_t addr, size_t size,
+ unsigned int *bit)
+{
+ FAR struct kasan_region_s *region;
+
+ for (region = g_region; region != NULL; region = region->next)
+ {
+ if (addr >= region->begin && addr < region->end)
+ {
+ DEBUGASSERT(addr + size <= region->end);
+ addr -= region->begin;
+ addr /= KASAN_SHADOW_SCALE;
+ *bit = addr % KASAN_BITS_PER_WORD;
+ return ®ion->shadow[addr / KASAN_BITS_PER_WORD];
+ }
+ }
+
+ return NULL;
+}
+
+static void kasan_report(uintptr_t addr, size_t size, bool is_write)
+{
+ static int recursion;
+
+ if (++recursion == 1)
+ {
+ _alert("kasan detected a %s access error, address at %0#"PRIxPTR
+ ", size is %zu\n", is_write ? "write" : "read", addr, size);
+ PANIC();
+ }
+
+ --recursion;
+}
+
+static bool kasan_is_poisoned(uintptr_t addr, size_t size)
+{
+ FAR uintptr_t *p;
+ unsigned int bit;
+
+ p = kasan_mem_to_shadow(addr + size - 1, 1, &bit);
+ return p && ((*p >> bit) & 1);
+}
+
+static void kasan_set_poison(uintptr_t addr, size_t size, bool poisoned)
+{
+ FAR uintptr_t *p;
+ unsigned int bit;
+ unsigned int nbit;
+ uintptr_t mask;
+
+ p = kasan_mem_to_shadow(addr, size, &bit);
+ DEBUGASSERT(p != NULL);
+
+ nbit = KASAN_BITS_PER_WORD - bit % KASAN_BITS_PER_WORD;
+ mask = KASAN_FIRST_WORD_MASK(bit);
+
+ size /= KASAN_SHADOW_SCALE;
+ while (size >= nbit)
+ {
+ if (poisoned)
+ {
+ *p++ |= mask;
+ }
+ else
+ {
+ *p++ &= ~mask;
+ }
+
+ bit += nbit;
+ size -= nbit;
+
+ nbit = KASAN_BITS_PER_WORD;
+ mask = UINTPTR_MAX;
+ }
+
+ if (size)
+ {
+ mask &= KASAN_LAST_WORD_MASK(bit + size);
+ if (poisoned)
+ {
+ *p |= mask;
+ }
+ else
+ {
+ *p &= ~mask;
+ }
+ }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/* Exported functions called from other mm module */
+
+void kasan_poison(FAR const void *addr, size_t size)
+{
+ kasan_set_poison((uintptr_t)addr, size, true);
+}
+
+void kasan_unpoison(FAR const void *addr, size_t size)
+{
+ kasan_set_poison((uintptr_t)addr, size, false);
+}
+
+void kasan_register(FAR void *addr, FAR size_t *size)
+{
+ FAR struct kasan_region_s *region;
+
+ region = (FAR struct kasan_region_s *)
+ ((FAR char *)addr + *size - KASAN_REGION_SIZE(*size));
+
+ region->begin = (uintptr_t)addr;
+ region->end = region->begin + *size;
+
+ _SEM_WAIT(&g_lock);
+ region->next = g_region;
+ g_region = region;
+ _SEM_POST(&g_lock);
+
+ kasan_poison(addr, *size);
+ *size -= KASAN_REGION_SIZE(*size);
+}
+
+/* Exported functions called from the compiler generated code */
+
+void __sanitizer_annotate_contiguous_container(FAR const void *beg,
+ FAR const void *end,
+ FAR const void *old_mid,
+ FAR const void *new_mid)
+{
+ /* Shut up compiler complaints */
+}
+
+void __asan_before_dynamic_init(FAR const char *module_name)
+{
+ /* Shut up compiler complaints */
+}
+
+void __asan_after_dynamic_init(void)
+{
+ /* Shut up compiler complaints */
+}
+
+void __asan_handle_no_return(void)
+{
+ /* Shut up compiler complaints */
+}
+
+void __asan_report_load_n_noabort(uintptr_t addr, size_t size)
+{
+ kasan_report(addr, size, false);
+}
+
+void __asan_report_store_n_noabort(uintptr_t addr, size_t size)
+{
+ kasan_report(addr, size, true);
+}
+
+void __asan_report_load16_noabort(uintptr_t addr)
+{
+ __asan_report_load_n_noabort(addr, 16);
+}
+
+void __asan_report_store16_noabort(uintptr_t addr)
+{
+ __asan_report_store_n_noabort(addr, 16);
+}
+
+void __asan_report_load8_noabort(uintptr_t addr)
+{
+ __asan_report_load_n_noabort(addr, 8);
+}
+
+void __asan_report_store8_noabort(uintptr_t addr)
+{
+ __asan_report_store_n_noabort(addr, 8);
+}
+
+void __asan_report_load4_noabort(uintptr_t addr)
+{
+ __asan_report_load_n_noabort(addr, 4);
+}
+
+void __asan_report_store4_noabort(uintptr_t addr)
+{
+ __asan_report_store_n_noabort(addr, 4);
+}
+
+void __asan_report_load2_noabort(uintptr_t addr)
+{
+ __asan_report_load_n_noabort(addr, 2);
+}
+
+void __asan_report_store2_noabort(uintptr_t addr)
+{
+ __asan_report_store_n_noabort(addr, 2);
+}
+
+void __asan_report_load1_noabort(uintptr_t addr)
+{
+ __asan_report_load_n_noabort(addr, 1);
+}
+
+void __asan_report_store1_noabort(uintptr_t addr)
+{
+ __asan_report_store_n_noabort(addr, 1);
+}
+
+void __asan_loadN_noabort(uintptr_t addr, size_t size)
+{
+ if (kasan_is_poisoned(addr, size))
+ {
+ kasan_report(addr, size, false);
+ }
+}
+
+void __asan_storeN_noabort(uintptr_t addr, size_t size)
+{
+ if (kasan_is_poisoned(addr, size))
+ {
+ kasan_report(addr, size, true);
+ }
+}
+
+void __asan_load16_noabort(uintptr_t addr)
+{
+ __asan_loadN_noabort(addr, 16);
+}
+
+void __asan_store16_noabort(uintptr_t addr)
+{
+ __asan_storeN_noabort(addr, 16);
+}
+
+void __asan_load8_noabort(uintptr_t addr)
+{
+ __asan_loadN_noabort(addr, 8);
+}
+
+void __asan_store8_noabort(uintptr_t addr)
+{
+ __asan_storeN_noabort(addr, 8);
+}
+
+void __asan_load4_noabort(uintptr_t addr)
+{
+ __asan_loadN_noabort(addr, 4);
+}
+
+void __asan_store4_noabort(uintptr_t addr)
+{
+ __asan_storeN_noabort(addr, 4);
+}
+
+void __asan_load2_noabort(uintptr_t addr)
+{
+ __asan_loadN_noabort(addr, 2);
+}
+
+void __asan_store2_noabort(uintptr_t addr)
+{
+ __asan_storeN_noabort(addr, 2);
+}
+
+void __asan_load1_noabort(uintptr_t addr)
+{
+ __asan_loadN_noabort(addr, 1);
+}
+
+void __asan_store1_noabort(uintptr_t addr)
+{
+ __asan_storeN_noabort(addr, 1);
+}
+
+void __asan_loadN(uintptr_t addr, size_t size)
+{
+ __asan_loadN_noabort(addr, size);
+}
+
+void __asan_storeN(uintptr_t addr, size_t size)
+{
+ __asan_storeN_noabort(addr, size);
+}
+
+void __asan_load16(uintptr_t addr)
+{
+ __asan_load16_noabort(addr);
+}
+
+void __asan_store16(uintptr_t addr)
+{
+ __asan_store16_noabort(addr);
+}
+
+void __asan_load8(uintptr_t addr)
+{
+ __asan_load8_noabort(addr);
+}
+
+void __asan_store8(uintptr_t addr)
+{
+ __asan_store8_noabort(addr);
+}
+
+void __asan_load4(uintptr_t addr)
+{
+ __asan_load4_noabort(addr);
+}
+
+void __asan_store4(uintptr_t addr)
+{
+ __asan_store4_noabort(addr);
+}
+
+void __asan_load2(uintptr_t addr)
+{
+ __asan_load2_noabort(addr);
+}
+
+void __asan_store2(uintptr_t addr)
+{
+ __asan_store2_noabort(addr);
+}
+
+void __asan_load1(uintptr_t addr)
+{
+ __asan_load1_noabort(addr);
+}
+
+void __asan_store1(uintptr_t addr)
+{
+ __asan_store1_noabort(addr);
+}
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
new file mode 100644
index 0000000..c6fd07c
--- /dev/null
+++ b/mm/kasan/kasan.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+ * mm/kasan/kasan.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __MM_KASAN_KASAN_H
+#define __MM_KASAN_KASAN_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stddef.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef CONFIG_MM_KASAN
+# define kasan_poison(addr, size)
+# define kasan_unpoison(addr, size)
+# define kasan_register(addr, size)
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+#ifdef CONFIG_MM_KASAN
+
+/****************************************************************************
+ * Name: kasan_poison
+ *
+ * Description:
+ * Mark the memory range as inaccessible
+ *
+ * Input Parameters:
+ * addr - range start address
+ * size - range size
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+void kasan_poison(FAR const void *addr, size_t size);
+
+/****************************************************************************
+ * Name: kasan_unpoison
+ *
+ * Description:
+ * Mark the memory range as accessible
+ *
+ * Input Parameters:
+ * addr - range start address
+ * size - range size
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+void kasan_unpoison(FAR const void *addr, size_t size);
+
+/****************************************************************************
+ * Name: kasan_register
+ *
+ * Description:
+ * Monitor the memory range for invalid access check
+ *
+ * Input Parameters:
+ * addr - range start address
+ * size - range size
+ *
+ * Returned Value:
+ * None.
+ *
+ * Note:
+ * The size is shrinked for the shadow region
+ *
+ ****************************************************************************/
+
+void kasan_register(FAR void *addr, FAR size_t *size);
+
+#endif /* CONFIG_MM_KASAN */
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MM_KASAN_KASAN_H */
diff --git a/mm/mm_heap/mm_free.c b/mm/mm_heap/mm_free.c
index c3545cf..c788649 100644
--- a/mm/mm_heap/mm_free.c
+++ b/mm/mm_heap/mm_free.c
@@ -31,6 +31,7 @@
#include <nuttx/mm/mm.h>
#include "mm_heap/mm.h"
+#include "kasan/kasan.h"
/****************************************************************************
* Private Functions
@@ -83,8 +84,12 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
return;
}
+ kasan_poison(mem, mm_malloc_size(mem));
+
if (mm_takesemaphore(heap) == false)
{
+ kasan_unpoison(mem, mm_malloc_size(mem));
+
/* We are in IDLE task & can't get sem, or meet -ESRCH return,
* which means we are in situations during context switching(See
* mm_takesemaphore() & getpid()). Then add to the delay list.
diff --git a/mm/mm_heap/mm_initialize.c b/mm/mm_heap/mm_initialize.c
index 9156111..4e2a21b 100644
--- a/mm/mm_heap/mm_initialize.c
+++ b/mm/mm_heap/mm_initialize.c
@@ -31,6 +31,7 @@
#include <nuttx/mm/mm.h>
#include "mm_heap/mm.h"
+#include "kasan/kasan.h"
/****************************************************************************
* Public Functions
@@ -86,6 +87,10 @@ void mm_addregion(FAR struct mm_heap_s *heap, FAR void *heapstart,
DEBUGASSERT(heapsize <= MMSIZE_MAX + 1);
#endif
+ /* Register to KASan for access check */
+
+ kasan_register(heapstart, &heapsize);
+
DEBUGVERIFY(mm_takesemaphore(heap));
/* Adjust the provided heap start and size so that they are both aligned
diff --git a/mm/mm_heap/mm_malloc.c b/mm/mm_heap/mm_malloc.c
index 598f553..a1262f5 100644
--- a/mm/mm_heap/mm_malloc.c
+++ b/mm/mm_heap/mm_malloc.c
@@ -32,6 +32,7 @@
#include <nuttx/mm/mm.h>
#include "mm_heap/mm.h"
+#include "kasan/kasan.h"
/****************************************************************************
* Pre-processor Definitions
@@ -228,25 +229,20 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
DEBUGASSERT(ret == NULL || mm_heapmember(heap, ret));
mm_givesemaphore(heap);
-#ifdef CONFIG_MM_FILL_ALLOCATIONS
if (ret)
{
- memset(ret, 0xaa, alignsize - SIZEOF_MM_ALLOCNODE);
- }
+ kasan_unpoison(ret, mm_malloc_size(ret));
+#ifdef CONFIG_MM_FILL_ALLOCATIONS
+ memset(ret, 0xaa, alignsize - SIZEOF_MM_ALLOCNODE);
#endif
-
- /* If CONFIG_DEBUG_MM is defined, then output the result of the allocation
- * to the SYSLOG.
- */
-
#ifdef CONFIG_DEBUG_MM
- if (!ret)
- {
- mwarn("WARNING: Allocation failed, size %zu\n", alignsize);
+ minfo("Allocated %p, size %zu\n", ret, alignsize);
+#endif
}
+#ifdef CONFIG_DEBUG_MM
else
{
- minfo("Allocated %p, size %zu\n", ret, alignsize);
+ mwarn("WARNING: Allocation failed, size %zu\n", alignsize);
}
#endif
diff --git a/mm/mm_heap/mm_memalign.c b/mm/mm_heap/mm_memalign.c
index 9d1bdd6..1fcd387 100644
--- a/mm/mm_heap/mm_memalign.c
+++ b/mm/mm_heap/mm_memalign.c
@@ -29,6 +29,7 @@
#include <nuttx/mm/mm.h>
#include "mm_heap/mm.h"
+#include "kasan/kasan.h"
/****************************************************************************
* Public Functions
@@ -111,6 +112,8 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment,
return NULL;
}
+ kasan_poison((FAR void *)rawchunk, mm_malloc_size((FAR void *)rawchunk));
+
/* We need to hold the MM semaphore while we muck with the chunks and
* nodelist.
*/
@@ -219,5 +222,9 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment,
}
mm_givesemaphore(heap);
+
+ kasan_unpoison((FAR void *)alignedchunk,
+ mm_malloc_size((FAR void *)alignedchunk));
+
return (FAR void *)alignedchunk;
}
diff --git a/mm/mm_heap/mm_realloc.c b/mm/mm_heap/mm_realloc.c
index 897201c..1842572 100644
--- a/mm/mm_heap/mm_realloc.c
+++ b/mm/mm_heap/mm_realloc.c
@@ -32,6 +32,7 @@
#include <nuttx/mm/mm.h>
#include "mm_heap/mm.h"
+#include "kasan/kasan.h"
/****************************************************************************
* Public Functions
@@ -123,6 +124,8 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
if (newsize < oldsize)
{
mm_shrinkchunk(heap, oldnode, newsize);
+ kasan_poison((FAR char *)oldnode + oldnode->size,
+ oldsize - oldnode->size);
}
/* Then return the original address */
@@ -264,12 +267,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
(next->preceding & MM_ALLOC_BIT);
}
- /* Now we have to move the user contents 'down' in memory. memcpy
- * should be safe for this.
- */
-
newmem = (FAR void *)((FAR char *)newnode + SIZEOF_MM_ALLOCNODE);
- memcpy(newmem, oldmem, oldsize - SIZEOF_MM_ALLOCNODE);
/* Now we want to return newnode */
@@ -335,6 +333,17 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
}
mm_givesemaphore(heap);
+
+ kasan_unpoison(newmem, mm_malloc_size(newmem));
+ if (newmem != oldmem)
+ {
+ /* Now we have to move the user contents 'down' in memory. memcpy
+ * should be safe for this.
+ */
+
+ memcpy(newmem, oldmem, oldsize - SIZEOF_MM_ALLOCNODE);
+ }
+
return newmem;
}
diff --git a/mm/umm_heap/umm_initialize.c b/mm/umm_heap/umm_initialize.c
index ca0fcc6..1eb726e 100644
--- a/mm/umm_heap/umm_initialize.c
+++ b/mm/umm_heap/umm_initialize.c
@@ -102,6 +102,7 @@ void umm_initialize(FAR void *heap_start, size_t heap_size)
void umm_try_initialize(void)
{
uintptr_t allocbase;
+ size_t npages = 1;
/* Return if the user heap is already initialized. */
@@ -110,16 +111,22 @@ void umm_try_initialize(void)
return;
}
- /* Allocate one page. If we provide a zero brkaddr to pgalloc(),
+#ifdef CONFIG_MM_KASAN
+ /* we have to commit all memory for the shadow region */
+
+ npages = CONFIG_ARCH_HEAP_NPAGES;
+#endif
+
+ /* If we provide a zero brkaddr to pgalloc(),
* it will create the first block in the correct virtual address
* space and return the start address of that block.
*/
- allocbase = pgalloc(0, 1);
+ allocbase = pgalloc(0, npages);
DEBUGASSERT(allocbase != 0);
/* Let umm_initialize do the real work. */
- umm_initialize((FAR void *)allocbase, CONFIG_MM_PGSIZE);
+ umm_initialize((FAR void *)allocbase, npages * CONFIG_MM_PGSIZE);
}
#endif
diff --git a/tools/nxstyle.c b/tools/nxstyle.c
index ae0c288..f2b44fb 100644
--- a/tools/nxstyle.c
+++ b/tools/nxstyle.c
@@ -276,6 +276,15 @@ static const char *g_white_list[] =
"SETATTR3resok",
"FS3args",
+ /* Ref:
+ * mm/kasan/kasan.c
+ */
+
+ "__asan_loadN",
+ "__asan_storeN",
+ "__asan_loadN_noabort",
+ "__asan_storeN_noabort",
+
NULL
};