1# Memory Corruption Check 2 3 4## Basic Concepts 5 6As an optional function of the kernel, memory corruption check is used to check the integrity of a dynamic memory pool. This mechanism can detect memory corruption errors in the memory pool in a timely manner and provide alerts. It helps reduce problem locating costs and increase troubleshooting efficiency. 7 8 9## Function Configuration 10 11**LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK** specifies the setting of the memory corruption check. This function is disabled by default. You can enable it in **Debug -> Enable integrity check or not**. 12 13If this macro is enabled, the memory pool integrity will be checked in real time upon each memory allocation. 14 15If this macro is not enabled, you can call **LOS_MemIntegrityCheck** to check the memory pool integrity when required. Using **LOS_MemIntegrityCheck** does not affect the system performance. However, the check accuracy decreases because the node header does not contain the magic number (which is available only when **LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK** is enabled). 16 17This check only detects the corrupted memory node and provides information about the previous node (because memory is contiguous, a node is most likely corrupted by the previous node). To further determine the location where the previous node is requested, you need to enable the memory leak check and use LRs to locate the fault. 18 19> **CAUTION**<br/> 20> If memory corruption check is enabled, a magic number is added to the node header, which increases the size of the node header. The real-time integrity check has a great impact on the performance. In performance-sensitive scenarios, you are advised to disable this function and use **LOS_MemIntegrityCheck** to check the memory pool integrity. 21 22 23## Development Guidelines 24 25 26### How to Develop 27 28Use **LOS_MemIntegrityCheck** to check for memory corruption. If no memory corruption occurs, **0** is returned and no log is output. If memory corruption occurs, the related log is output. For details, see the output of the following example. 29 30 31### Development Example 32 33This example implements the following: 34 351. Request two physically adjacent memory blocks. 36 372. Use **memset** to construct an out-of-bounds access and overwrites the first four bytes of the next node. 38 393. Call **LOS_MemIntegrityCheck** to check for memory corruption. 40 41 42**Sample Code** 43 44You can add the test function of the sample code to **TestTaskEntry** in **kernel/liteos_a/testsuites/kernel/src/osTest.c** for testing. 45The sample code is as follows: 46 47 48 49```c 50#include <stdio.h> 51#include <string.h> 52#include "los_memory.h" 53#include "los_config.h" 54 55void MemIntegrityTest(void) 56{ 57 /* Request two physically adjacent memory blocks. */ 58 void *ptr1 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8); 59 void *ptr2 = LOS_MemAlloc(LOSCFG_SYS_HEAP_ADDR, 8); 60 /* Construct an out-of-bounds access to cause memory corruption. The memory block of the first node is 8 bytes. Clearing 12 bytes overwrites the header of the second memory node. */ 61 memset(ptr1, 0, 8 + 4); 62 LOS_MemIntegrityCheck(LOSCFG_SYS_HEAP_ADDR); 63} 64``` 65 66**Verification** 67 68 69The log is as follows: 70 71 72 73``` 74[ERR][OsMemMagicCheckPrint], 2028, memory check error! 75memory used but magic num wrong, magic num = 0x00000000 /* Error information, indicating that the first four bytes, that is, the magic number, of the next node are corrupted. */ 76 77 broken node head: 0x20003af0 0x00000000 0x80000020, prev node head: 0x20002ad4 0xabcddcba 0x80000020 78/* Key information about the corrupted node and its previous node, including the address of the previous node, magic number of the node, and sizeAndFlag of the node. In this example, the magic number of the corrupted node is cleared. */ 79 80 broken node head LR info: /* The node LR information can be output only after the memory leak check is enabled. */ 81 LR[0]:0x0800414e 82 LR[1]:0x08000cc2 83 LR[2]:0x00000000 84 85 pre node head LR info: /* Based on the LR information, you can find where the previous node is requested in the assembly file and then perform further analysis. */ 86 LR[0]:0x08004144 87 LR[1]:0x08000cc2 88 LR[2]:0x00000000 89[ERR]Memory integrity check error, cur node: 0x20003b10, pre node: 0x20003af0 /* Addresses of the corrupted node and its previous node */ 90``` 91