[v3,09/10] memarea: detect memory corruption based on magic

Message ID 20220924074951.31814-10-fengchengwen@huawei.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series introduce memarea library |

Commit Message

Chengwen Feng Sept. 24, 2022, 7:49 a.m. UTC
  This patch provides lightweight mechanism for detecting memory
corruption which based on magic field in each element node.

Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
 lib/memarea/memarea_private.h |  2 ++
 lib/memarea/rte_memarea.c     | 29 ++++++++++++++++++++++++++---
 2 files changed, 28 insertions(+), 3 deletions(-)
  

Patch

diff --git a/lib/memarea/memarea_private.h b/lib/memarea/memarea_private.h
index 08735ca81f..4f5393e6f9 100644
--- a/lib/memarea/memarea_private.h
+++ b/lib/memarea/memarea_private.h
@@ -7,10 +7,12 @@ 
 
 #include <rte_memarea.h>
 
+#define MEMAREA_ELEM_MAGIC_NUM		0xbeef1234
 #define MEMAREA_FREE_ELEM_COOKIE	0xFFFFFFFF
 
 struct memarea_elem {
 	size_t   size;
+	uint32_t magic;
 	uint32_t cookie;
 	int32_t  refcnt; /* Non-zero indicates that it has been allocated */
 	TAILQ_ENTRY(memarea_elem) elem_node;
diff --git a/lib/memarea/rte_memarea.c b/lib/memarea/rte_memarea.c
index f45191aa7f..c81d4dd3fa 100644
--- a/lib/memarea/rte_memarea.c
+++ b/lib/memarea/rte_memarea.c
@@ -135,6 +135,7 @@  rte_memarea_create(const struct rte_memarea_param *init)
 	ma->top_addr = (void *)((uintptr_t)addr + init->total_sz - 1);
 	elem = addr;
 	elem->size = init->total_sz - sizeof(struct memarea_elem);
+	elem->magic = MEMAREA_ELEM_MAGIC_NUM;
 	elem->cookie = MEMAREA_FREE_ELEM_COOKIE;
 	elem->refcnt = 0;
 	TAILQ_INSERT_TAIL(&ma->elem_list, elem, elem_node);
@@ -194,6 +195,7 @@  memarea_add_node(struct rte_memarea *ma, struct memarea_elem *elem, size_t need_
 	new_elem = (struct memarea_elem *)((uintptr_t)elem + sizeof(struct memarea_elem) +
 					   align_size);
 	new_elem->size = elem->size - align_size - sizeof(struct memarea_elem);
+	new_elem->magic = MEMAREA_ELEM_MAGIC_NUM;
 	new_elem->cookie = MEMAREA_FREE_ELEM_COOKIE;
 	new_elem->refcnt = 0;
 	TAILQ_INSERT_AFTER(&ma->elem_list, elem, new_elem, elem_node);
@@ -221,6 +223,8 @@  rte_memarea_alloc(struct rte_memarea *ma, size_t size, uint32_t cookie)
 
 	memarea_lock(ma);
 	TAILQ_FOREACH(elem, &ma->free_list, free_node) {
+		if (unlikely(elem->magic != MEMAREA_ELEM_MAGIC_NUM))
+			break;
 		if (elem->size < size)
 			continue;
 		if (memarea_whether_add_node(elem->size, size))
@@ -253,6 +257,7 @@  memarea_merge_node(struct rte_memarea *ma, struct memarea_elem *curr,
 {
 	curr->size += next->size + sizeof(struct memarea_elem);
 	next->size = 0;
+	next->magic = ~MEMAREA_ELEM_MAGIC_NUM;
 	next->cookie = 0;
 	TAILQ_REMOVE(&ma->elem_list, next, elem_node);
 	if (del_next_from_free)
@@ -295,6 +300,13 @@  rte_memarea_update_refcnt(struct rte_memarea *ma, void *ptr, int16_t value)
 		return;
 
 	memarea_lock(ma);
+	if (unlikely(elem->magic != MEMAREA_ELEM_MAGIC_NUM)) {
+		RTE_LOG(ERR, MEMAREA, "memarea: %s magic: 0x%x check fail!\n",
+			ma->init.name, elem->magic);
+		memarea_unlock(ma);
+		return;
+	}
+
 	if (ptr < ma->area_addr || ptr > ma->top_addr) {
 		rte_memarea_update_refcnt(ma->init.bak_memarea, ptr, value);
 		memarea_unlock(ma);
@@ -348,8 +360,11 @@  memarea_elem_list_num(struct rte_memarea *ma)
 	struct memarea_elem *elem;
 	uint32_t num = 0;
 
-	TAILQ_FOREACH(elem, &ma->elem_list, elem_node)
+	TAILQ_FOREACH(elem, &ma->elem_list, elem_node) {
+		if (elem->magic != MEMAREA_ELEM_MAGIC_NUM)
+			break;
 		num++;
+	}
 
 	return num;
 }
@@ -360,8 +375,11 @@  memarea_free_list_num(struct rte_memarea *ma)
 	struct memarea_elem *elem;
 	uint32_t num = 0;
 
-	TAILQ_FOREACH(elem, &ma->free_list, free_node)
+	TAILQ_FOREACH(elem, &ma->free_list, free_node) {
+		if (elem->magic != MEMAREA_ELEM_MAGIC_NUM)
+			break;
 		num++;
+	}
 
 	return num;
 }
@@ -372,9 +390,14 @@  memarea_dump_all(struct rte_memarea *ma, FILE *f)
 	struct memarea_elem *elem;
 
 	fprintf(f, "  regions:\n");
-	TAILQ_FOREACH(elem, &ma->elem_list, elem_node)
+	TAILQ_FOREACH(elem, &ma->elem_list, elem_node) {
+		if (elem->magic != MEMAREA_ELEM_MAGIC_NUM) {
+			fprintf(f, "    magic: 0x%x chech fail!\n", elem->magic);
+			break;
+		}
 		fprintf(f, "    size: 0x%zx cookie: 0x%x refcnt: %d\n",
 			elem->size, elem->cookie, elem->refcnt);
+	}
 }
 
 int