mirror of
https://github.com/apache/nuttx.git
synced 2025-01-12 22:08:35 +08:00
mte/kasan: Implementing KASAN memory protection for ARM64 hardware MTE
1. Add mte_tags.c, which will call arm64_mte to implement tagging of memory blocks by operating registers 2. please use arm64/mte, it default enable MM_KASAN_MTE_TAGS, run log: ➜ NX git:(mm) ✗ qemu-system-aarch64 -cpu max -nographic \ -machine virt,virtualization=on,gic-version=3,mte=on \ -chardev stdio,id=con,mux=on, -serial chardev:con \ -mon chardev=con,mode=readline -kernel ./nuttx/nuttx -s - Ready to Boot Primary CPU - Boot from EL2 - Boot from EL1 - Boot to C runtime for OS Initialize mm_initialize: Heap: name=Umem, start=0x403f2000 size=130080768 mm_addregion: [Umem] Region 1: base=0x403f23a0 size=130079840 mm_malloc: Allocated 0xf8000000403f23e0, size 144 mm_malloc: Allocated 0xfe000000403f2470, size 80 mm_malloc: Allocated 0xfe000000403f24c0, size 64 mm_malloc: Allocated 0xfe000000403f2500, size 96 mm_malloc: Allocated 0xff000000403f2560, size 96 mm_malloc: Allocated 0xf7000000403f25c0, size 96 mm_malloc: Allocated 0xff000000403f2620, size 96 mm_malloc: Allocated 0xfe000000403f2680, size 96 mm_malloc: Allocated 0xfe000000403f26e0, size 64 mm_malloc: Allocated 0xf1000000403f2720, size 64 mm_malloc: Allocated 0xf9000000403f2760, size 336 mm_malloc: Allocated 0xf6000000403f28b0, size 8208 mm_malloc: Allocated 0xf4000000403f48c0, size 1584 mm_malloc: Allocated 0xfa000000403f4ef0, size 64 mm_malloc: Allocated 0xf8000000403f4f30, size 64 mm_malloc: Allocated 0xfe000000403f4f70, size 8208 mm_malloc: Allocated 0xfe000000403f6f80, size 80 mm_malloc: Allocated 0xfe000000403f6fd0, size 96 mm_malloc: Allocated 0xf7000000403f7030, size 96 mm_malloc: Allocated 0xf7000000403f7090, size 336 mm_malloc: Allocated 0xfc000000403f71e0, size 96 mm_malloc: Allocated 0xfd000000403f7240, size 912 NuttShell (NSH) nsh> nsh> mtetest mm_malloc: Allocated 0xf4000000403f75d0, size 1584 mm_malloc: Allocated 0xfd000000403f7c00, size 64 mm_malloc: Allocated 0xff000000403f7c40, size 64 mm_malloc: Allocated 0xfe000000403f7c80, size 8208 Spawning process for test: mtetest1 mm_malloc: Allocated 0xf4000000403f9c90, size 1584 mm_malloc: Allocated 0xfb000000403fa2c0, size 64 mm_malloc: Allocated 0xf5000000403fa300, size 64 mm_malloc: Allocated 0xfd000000403fa340, size 8208 Running test: mtetest1 mm_free: Freeing 0xf5000000403fa300 mm_free: Freeing 0xfb000000403fa2c0 mm_free: Freeing 0xfd000000403fa340 mm_free: Freeing 0xf4000000403f9c90 Test 'mtetest1' completed Spawning process for test: mtetest2 mm_malloc: Allocated 0xf9000000403f9c90, size 1584 mm_malloc: Allocated 0xfd000000403fa2c0, size 64 mm_malloc: Allocated 0xfd000000403fa300, size 64 mm_malloc: Allocated 0xfb000000403fa340, size 8208 Running test: mtetest2 mm_free: Freeing 0xfd000000403fa300 mm_free: Freeing 0xfd000000403fa2c0 mm_free: Freeing 0xfb000000403fa340 mm_free: Freeing 0xf9000000403f9c90 Test 'mtetest2' completed Spawning process for test: mtetest3 mm_malloc: Allocated 0xf5000000403f9c90, size 1584 mm_malloc: Allocated 0xf7000000403fa2c0, size 64 mm_malloc: Allocated 0xfd000000403fa300, size 64 mm_malloc: Allocated 0xf4000000403fa340, size 8208 Running test: mtetest3 mm_free: Freeing 0xfd000000403fa300 mm_free: Freeing 0xf7000000403fa2c0 mm_free: Freeing 0xf4000000403fa340 mm_free: Freeing 0xf5000000403f9c90 Test 'mtetest3' completed Spawning process for test: mtetest4 mm_malloc: Allocated 0xf8000000403f9c90, size 1584 mm_malloc: Allocated 0xfb000000403fa2c0, size 64 mm_malloc: Allocated 0xf4000000403fa300, size 64 mm_malloc: Allocated 0xfe000000403fa340, size 8208 Running test: mtetest4 mm_free: Freeing 0xf4000000403fa300 mm_free: Freeing 0xfb000000403fa2c0 mm_free: Freeing 0xfe000000403fa340 mm_free: Freeing 0xf8000000403f9c90 Test 'mtetest4' completed Spawning process for test: mtetest5 mm_malloc: Allocated 0xf2000000403f9c90, size 1584 mm_malloc: Allocated 0xf5000000403fa2c0, size 64 mm_malloc: Allocated 0xf8000000403fa300, size 64 mm_malloc: Allocated 0xfb000000403fa340, size 8208 Running test: mtetest5 mm_free: Freeing 0xf8000000403fa300 mm_free: Freeing 0xf5000000403fa2c0 mm_free: Freeing 0xfb000000403fa340 mm_free: Freeing 0xf2000000403f9c90 Test 'mtetest5' completed Spawning process for test: Thread switch MTE test mm_malloc: Allocated 0xf4000000403f9c90, size 1584 mm_malloc: Allocated 0xff000000403fa2c0, size 64 mm_malloc: Allocated 0xfe000000403fa300, size 64 mm_malloc: Allocated 0xfb000000403fa340, size 8208 Running test: Thread switch MTE test mm_malloc: Allocated 0xf2000000403fc350, size 352 mm_malloc: Allocated 0xf4000000403fc4b0, size 8208 mm_malloc: Allocated 0xf4000000403fe4c0, size 352 mm_malloc: Allocated 0xfa000000403fe620, size 8208 Process 1 holding lock Process 2 holding lock Process 1 holding lock again default_fatal_handler: (IFSC/DFSC) for Data/Instruction aborts: synchronous tag check fault arm64_exception_handler: CurrentEL: MODE_EL1 arm64_exception_handler: ESR_ELn: 0x96000011 arm64_exception_handler: FAR_ELn: 0x6000000403ee2f0 arm64_exception_handler: ELR_ELn: 0x402b3e98 print_ec_cause: DABT (current EL) print_ec_cause: Data Abort taken without a change in Exception level dump_assert_info: Current Version: NuttX 0.0.0 a3fd5888b4-dirty Jan 8 2025 11:54:02 arm64 dump_assert_info: Assertion failed panic: at file: common/arm64_fatal.c:573 task: mtetest process: mtetest 0x402a9360 up_dump_register: stack = 0xf6000000403f1328 up_dump_register: x0: 0x200 x1: 0x100 up_dump_register: x2: 0x1000000403e1330 x3: 0x9000000 up_dump_register: x4: 0x0 x5: 0x1 up_dump_register: x6: 0x403d0638 x7: 0x1 up_dump_register: x8: 0xa x9: 0x0 up_dump_register: x10: 0x0 x11: 0x0 up_dump_register: x12: 0x0 x13: 0x0 up_dump_register: x14: 0x0 x15: 0x0 up_dump_register: x16: 0x0 x17: 0x0 up_dump_register: x18: 0x0 x19: 0xf3000000403ef270 up_dump_register: x20: 0xf3000000403ef288 x21: 0x403c13df up_dump_register: x22: 0x403c13f6 x23: 0x0 up_dump_register: x24: 0x0 x25: 0x0 up_dump_register: x26: 0x0 x27: 0x0 up_dump_register: x28: 0x0 x29: 0xf6000000403f1450 up_dump_register: x30: 0x402a93c0 up_dump_register: up_dump_register: STATUS Registers: up_dump_register: SPSR: 0x20000005 up_dump_register: ELR: 0x402a93f8 up_dump_register: SP_EL0: 0xf6000000403f1388 up_dump_register: SP_ELX: 0xf6000000403f1450 up_dump_register: EXE_DEPTH: 0xfffffffffffffffc dump_tasks: PID GROUP PRI POLICY TYPE NPX STATE EVENT SIGMASK STACKBASE STACKSIZE USED FILLED COMMAND dump_tasks: ---- --- --- -------- ------- --- ------- ---------- ---------------- 0x403e2000 4096 336 8.2% irq dump_task: 0 0 0 FIFO Kthread - Ready 0000000000000000 0x403e3010 8176 1728 21.1% Idle_Task dump_task: 1 0 192 RR Kthread - Waiting Semaphore 0000000000000000 0xfc000000403e5900 8112 488 6.0% hpwork 0x403d04b8 0x403d0500 dump_task: 2 2 100 RR Task - Waiting Semaphore 0000000000000000 0xfe000000403e7fa0 8144 2672 32.8% nsh_main dump_task: 3 3 101 RR Task - Waiting Semaphore 0000000000000000 0xf6000000403eacb0 8144 1744 21.4% mtetest dump_task: 9 9 101 RR Task - Waiting Semaphore 0000000000000000 0xf3000000403ed390 8112 1784 21.9% mtetest Thread switch MTE test dump_task: 10 9 101 RR pthread - Running 0000000000000000 0xf6000000403ef4c0 8176 2072 25.3% mtetest 0x402a9360 0xf3000000403ef270 dump_task: 11 9 101 RR pthread - Waiting Signal 0000000000000000 0xfc000000403f1630 8176 808 9.8% mtetest 0x402a92e8 0xf3000000403ef270 Signed-off-by: wangmingrong1 <wangmingrong1@xiaomi.com>
This commit is contained in:
parent
cdb95b8b60
commit
e1b776f874
11 changed files with 313 additions and 14 deletions
58
arch/arm64/include/mte.h
Normal file
58
arch/arm64/include/mte.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/****************************************************************************
|
||||
* arch/arm64/include/mte.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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 ___ARCH_ARM64_SRC_COMMON_ARM64_MTE_H
|
||||
#define ___ARCH_ARM64_SRC_COMMON_ARM64_MTE_H
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Initialize MTE settings and enable memory tagging */
|
||||
|
||||
void arm64_mte_init(void);
|
||||
|
||||
/* Enable MTE by setting the TCF1 bit in SCTLR_EL1 */
|
||||
|
||||
void arm64_mte_enable(void);
|
||||
|
||||
/* Disable MTE by clearing the TCF1 bit in SCTLR_EL1 */
|
||||
|
||||
void arm64_mte_disable(void);
|
||||
|
||||
/* Set memory tags for a given memory range */
|
||||
|
||||
void arm64_mte_set_tag(const void *addr, size_t size);
|
||||
|
||||
/* Get a random label based on the address through the mte register */
|
||||
|
||||
uint8_t arm64_mte_get_random_tag(const void *addr);
|
||||
|
||||
/* Get the address without label */
|
||||
|
||||
FAR void *arm64_mte_get_untagged_addr(const void *addr);
|
||||
|
||||
/* Get the address with label */
|
||||
|
||||
FAR void *arm64_mte_get_tagged_addr(const void *addr, uint8_t tag);
|
||||
|
||||
#endif /* ___ARCH_ARM64_SRC_COMMON_ARM64_MTE_H */
|
|
@ -506,12 +506,6 @@ uint64_t arm64_get_mpid(int cpu);
|
|||
int arm64_get_cpuid(uint64_t mpid);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM64_MTE
|
||||
void arm64_enable_mte(void);
|
||||
#else
|
||||
#define arm64_enable_mte()
|
||||
#endif
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* ___ARCH_ARM64_SRC_COMMON_ARM64_ARCH_H */
|
||||
|
|
|
@ -170,8 +170,10 @@
|
|||
* in the address range [59:55] = 0b00000 are unchecked accesses.
|
||||
*/
|
||||
|
||||
#define TCR_TCMA0 (1ULL << 57)
|
||||
#define TCR_TCMA1 (1ULL << 58)
|
||||
#define TCR_TCMA0 BIT(57)
|
||||
#define TCR_TCMA1 BIT(58)
|
||||
#define TCR_MTX0_SHIFT BIT(60)
|
||||
#define TCR_MTX1_SHIFT BIT(61)
|
||||
|
||||
#define TCR_PS_BITS_4GB 0x0ULL
|
||||
#define TCR_PS_BITS_64GB 0x1ULL
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "arm64_arch.h"
|
||||
#include "arm64_mmu.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
|
@ -36,11 +37,17 @@
|
|||
|
||||
#define GCR_EL1_VAL 0x10001
|
||||
|
||||
/* The alignment length of the MTE must be a multiple of sixteen */
|
||||
|
||||
#define MTE_MM_AILGN 16
|
||||
|
||||
#define MTE_TAG_SHIFT 56
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static int arm64_mte_is_support(void)
|
||||
static int mte_is_support(void)
|
||||
{
|
||||
int supported;
|
||||
__asm__ volatile (
|
||||
|
@ -53,15 +60,86 @@ static int arm64_mte_is_support(void)
|
|||
return supported != 0;
|
||||
}
|
||||
|
||||
static void mte_set_tcf(bool enable)
|
||||
{
|
||||
uint64_t val = read_sysreg(sctlr_el1);
|
||||
|
||||
if (enable)
|
||||
{
|
||||
val |= SCTLR_TCF1_BIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
val &= ~SCTLR_TCF1_BIT;
|
||||
}
|
||||
|
||||
write_sysreg(val, sctlr_el1);
|
||||
}
|
||||
|
||||
static inline uint8_t mte_get_ptr_tag(const void *ptr)
|
||||
{
|
||||
return 0xf0 | (uint8_t)(((uint64_t)(ptr)) >> MTE_TAG_SHIFT);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
void arm64_enable_mte(void)
|
||||
uint8_t arm64_mte_get_random_tag(const void *addr)
|
||||
{
|
||||
asm("irg %0, %0" : "=r" (addr));
|
||||
|
||||
return mte_get_ptr_tag(addr);
|
||||
}
|
||||
|
||||
FAR void *arm64_mte_get_untagged_addr(const void *addr)
|
||||
{
|
||||
return (FAR void *)
|
||||
(((uint64_t)(addr)) & ~((uint64_t)0xff << MTE_TAG_SHIFT));
|
||||
}
|
||||
|
||||
FAR void *arm64_mte_get_tagged_addr(const void *addr, uint8_t tag)
|
||||
{
|
||||
return (FAR void *)
|
||||
(((uint64_t)(addr)) | ((uint64_t)tag << MTE_TAG_SHIFT));
|
||||
}
|
||||
|
||||
/* Disable MTE by clearing the TCF1 bit in SCTLR_EL1 */
|
||||
|
||||
void arm64_mte_disable(void)
|
||||
{
|
||||
mte_set_tcf(false);
|
||||
}
|
||||
|
||||
/* Enable MTE by setting the TCF1 bit in SCTLR_EL1 */
|
||||
|
||||
void arm64_mte_enable(void)
|
||||
{
|
||||
mte_set_tcf(true);
|
||||
}
|
||||
|
||||
/* Set memory tags for a given memory range */
|
||||
|
||||
void arm64_mte_set_tag(const void *addr, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
DEBUGASSERT((uintptr_t)addr % MTE_MM_AILGN == 0);
|
||||
DEBUGASSERT(size % MTE_MM_AILGN == 0);
|
||||
|
||||
for (i = 0; i < size; i += MTE_MM_AILGN)
|
||||
{
|
||||
asm("stg %0, [%0]" : : "r"(addr + i));
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize MTE settings and enable memory tagging */
|
||||
|
||||
void arm64_mte_init(void)
|
||||
{
|
||||
uint64_t val;
|
||||
|
||||
if (!arm64_mte_is_support())
|
||||
if (!mte_is_support())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -78,6 +156,14 @@ void arm64_enable_mte(void)
|
|||
assert(!(read_sysreg(ttbr0_el1) & TTBR_CNP_BIT));
|
||||
assert(!(read_sysreg(ttbr1_el1) & TTBR_CNP_BIT));
|
||||
|
||||
/* Controls the default value for skipping high bytes */
|
||||
|
||||
val = read_sysreg(tcr_el1);
|
||||
val |= TCR_TCMA1;
|
||||
write_sysreg(val, tcr_el1);
|
||||
|
||||
/* Enable the MTE function */
|
||||
|
||||
val = read_sysreg(sctlr_el1);
|
||||
val |= SCTLR_ATA_BIT | SCTLR_TCF1_BIT;
|
||||
write_sysreg(val, sctlr_el1);
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
# include <nuttx/page.h>
|
||||
#endif
|
||||
|
||||
#include <arch/mte.h>
|
||||
#include <arch/chip/chip.h>
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
@ -161,7 +162,9 @@ void arm64_chip_boot(void)
|
|||
|
||||
arm64_mmu_init(true);
|
||||
|
||||
arm64_enable_mte();
|
||||
#ifdef CONFIG_ARM64_MTE
|
||||
arm64_mte_init();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEVICE_TREE
|
||||
fdt_register((const char *)0x40000000);
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
# define kasan_stop()
|
||||
# define kasan_debugpoint(t,a,s) 0
|
||||
# define kasan_init_early()
|
||||
# define kasan_hw_open()
|
||||
# define kasan_hw_close()
|
||||
#else
|
||||
|
||||
# define kasan_init_early() kasan_stop()
|
||||
|
@ -201,6 +203,23 @@ void kasan_stop(void);
|
|||
|
||||
int kasan_debugpoint(int type, FAR void *addr, size_t size);
|
||||
|
||||
#ifndef CONFIG_MM_KASAN_MTE_TAGS
|
||||
# define kasan_hw_open()
|
||||
# define kasan_hw_close()
|
||||
#else
|
||||
/****************************************************************************
|
||||
* Name: kasan_hw_open
|
||||
****************************************************************************/
|
||||
|
||||
void kasan_hw_open(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: kasan_hw_open
|
||||
****************************************************************************/
|
||||
|
||||
void kasan_hw_close(void);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
13
mm/Kconfig
13
mm/Kconfig
|
@ -348,10 +348,22 @@ config MM_KASAN_SW_TAGS
|
|||
---help---
|
||||
KAsan based on software tags
|
||||
|
||||
config MM_KASAN_MTE_TAGS
|
||||
bool "KAsan MTE tags"
|
||||
depends on ARM64_MTE
|
||||
select MM_KASAN_NO_INSTRUMENT
|
||||
---help---
|
||||
KAsan based on hardware tags
|
||||
|
||||
endchoice
|
||||
|
||||
config MM_KASAN_NO_INSTRUMENT
|
||||
bool
|
||||
default n
|
||||
|
||||
config MM_KASAN_ALL
|
||||
bool "Enable KASan for the entire image"
|
||||
depends on !MM_KASAN_NO_INSTRUMENT
|
||||
default y
|
||||
---help---
|
||||
This option activates address sanitizer for the entire image.
|
||||
|
@ -366,6 +378,7 @@ config MM_KASAN_REGIONS
|
|||
|
||||
config MM_KASAN_WATCHPOINT
|
||||
int "Kasan watchpoint maximum number"
|
||||
depends on !MM_KASAN_NO_INSTRUMENT
|
||||
default 0
|
||||
---help---
|
||||
The maximum number of watchpoints that can be set by KASan.
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
# include "generic.c"
|
||||
#elif defined(CONFIG_MM_KASAN_SW_TAGS)
|
||||
# include "sw_tags.c"
|
||||
#elif defined(CONFIG_MM_KASAN_MTE_TAGS)
|
||||
# include "mte_tags.c"
|
||||
#else
|
||||
# define kasan_is_poisoned(addr, size) false
|
||||
#endif
|
||||
|
@ -123,6 +125,8 @@ static uint32_t g_region_init;
|
|||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_MM_KASAN_MTE_TAGS
|
||||
|
||||
static void kasan_show_memory(FAR const uint8_t *addr, size_t size,
|
||||
size_t dumpsize)
|
||||
{
|
||||
|
@ -252,6 +256,10 @@ static inline void kasan_check_report(FAR const void *addr, size_t size,
|
|||
# endif
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
#define kasan_check_report(addr, size, is_write, return_address)
|
||||
#define kasan_report(addr, size, is_write, return_address)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
|
|
97
mm/kasan/mte_tags.c
Normal file
97
mm/kasan/mte_tags.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
/****************************************************************************
|
||||
* mm/kasan/mte_tags.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/mm/mm.h>
|
||||
#include <nuttx/mm/kasan.h>
|
||||
|
||||
#include <arch/mte.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
static void *kasan_set_poison(FAR const void *addr,
|
||||
size_t size,
|
||||
uint8_t tag)
|
||||
{
|
||||
FAR const void *tag_addr;
|
||||
|
||||
/* Get random labels and the addresses after labeling */
|
||||
|
||||
tag_addr = arm64_mte_get_tagged_addr(addr, tag);
|
||||
|
||||
/* Add MTE hardware label to memory block */
|
||||
|
||||
arm64_mte_set_tag(tag_addr, size);
|
||||
|
||||
return (FAR void *)tag_addr;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
void kasan_hw_open(void)
|
||||
{
|
||||
arm64_mte_enable();
|
||||
}
|
||||
|
||||
void kasan_hw_close(void)
|
||||
{
|
||||
arm64_mte_disable();
|
||||
}
|
||||
|
||||
FAR void *kasan_reset_tag(FAR const void *addr)
|
||||
{
|
||||
return arm64_mte_get_untagged_addr(addr);
|
||||
}
|
||||
|
||||
void kasan_poison(FAR const void *addr, size_t size)
|
||||
{
|
||||
uint8_t tag = arm64_mte_get_random_tag(addr);
|
||||
|
||||
kasan_set_poison(addr, size, tag);
|
||||
}
|
||||
|
||||
FAR void *kasan_unpoison(FAR const void *addr, size_t size)
|
||||
{
|
||||
uint8_t tag = arm64_mte_get_random_tag(addr);
|
||||
|
||||
return kasan_set_poison(addr, size, tag);
|
||||
}
|
||||
|
||||
void kasan_register(FAR void *addr, FAR size_t *size)
|
||||
{
|
||||
uint8_t tag = arm64_mte_get_random_tag(addr);
|
||||
|
||||
kasan_set_poison(addr, *size, tag);
|
||||
}
|
||||
|
||||
void kasan_unregister(FAR void *addr)
|
||||
{
|
||||
}
|
|
@ -49,6 +49,8 @@ static void add_delaylist(FAR struct mm_heap_s *heap, FAR void *mem)
|
|||
|
||||
/* Delay the deallocation until a more appropriate time. */
|
||||
|
||||
kasan_hw_close();
|
||||
|
||||
flags = up_irq_save();
|
||||
|
||||
# ifdef CONFIG_DEBUG_ASSERTIONS
|
||||
|
@ -67,6 +69,8 @@ static void add_delaylist(FAR struct mm_heap_s *heap, FAR void *mem)
|
|||
|
||||
up_irq_restore(flags);
|
||||
#endif
|
||||
|
||||
kasan_hw_open();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/mm/kasan.h>
|
||||
#include <nuttx/mm/mm.h>
|
||||
|
||||
#include "mm_heap/mm.h"
|
||||
|
@ -59,6 +60,10 @@
|
|||
|
||||
int mm_lock(FAR struct mm_heap_s *heap)
|
||||
{
|
||||
int ret;
|
||||
|
||||
kasan_hw_close();
|
||||
|
||||
#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
|
||||
/* Check current environment */
|
||||
|
||||
|
@ -69,12 +74,19 @@ int mm_lock(FAR struct mm_heap_s *heap)
|
|||
* Or, touch the heap internal data directly.
|
||||
*/
|
||||
|
||||
return nxmutex_is_locked(&heap->mm_lock) ? -EAGAIN : 0;
|
||||
ret = nxmutex_is_locked(&heap->mm_lock) ? -EAGAIN : 0;
|
||||
# else
|
||||
/* Can't take mutex in SMP interrupt handler */
|
||||
|
||||
return -EAGAIN;
|
||||
ret = -EAGAIN;
|
||||
# endif
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
kasan_hw_open();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -90,6 +102,7 @@ int mm_lock(FAR struct mm_heap_s *heap)
|
|||
|
||||
if (_SCHED_GETTID() < 0)
|
||||
{
|
||||
kasan_hw_open();
|
||||
return -ESRCH;
|
||||
}
|
||||
else
|
||||
|
@ -111,9 +124,11 @@ void mm_unlock(FAR struct mm_heap_s *heap)
|
|||
#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
|
||||
if (up_interrupt_context())
|
||||
{
|
||||
kasan_hw_open();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
DEBUGVERIFY(nxmutex_unlock(&heap->mm_lock));
|
||||
kasan_hw_open();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue