From cf60179805a6ea72cf5133358a61703eb2dae64d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=9A=E7=A5=96=E6=9C=9B?= <5171267+gongzuwang@user.noreply.gitee.com> Date: Fri, 15 May 2026 10:23:35 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E4=BF=AE=E5=A4=8DPmpClearRegion=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E5=88=A4=E6=96=AD=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c b/Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c index 93117c6fb..3c967f409 100644 --- a/Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c +++ b/Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c @@ -114,7 +114,7 @@ x_err_t PmpClearRegion(void *task_pmp, x_ubase addr) if (!IsDoubleLinkListEmpty(&pmp->tor_list)) { DOUBLE_LINKLIST_FOR_EACH(link, &pmp->tor_list) { tor_node = CONTAINER_OF(link, struct PmpRegionTor, link); - if ( addr = tor_node->start ){ + if ( addr == tor_node->start ){ pmp->count = pmp->count -2; goto __free ; } @@ -123,7 +123,7 @@ x_err_t PmpClearRegion(void *task_pmp, x_ubase addr) if (!IsDoubleLinkListEmpty(&pmp->tor_swap_list)) { DOUBLE_LINKLIST_FOR_EACH(link, &pmp->tor_swap_list) { tor_node = CONTAINER_OF(link, struct PmpRegionTor, link); - if ( addr = tor_node->start ) { + if ( addr == tor_node->start ) { goto __free; } } -- 2.34.1 From 4ebe448542b03e5c4c5285c51f95f1a0f76da34d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=9A=E7=A5=96=E6=9C=9B?= <5171267+gongzuwang@user.noreply.gitee.com> Date: Fri, 15 May 2026 10:24:58 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=E4=BF=AE=E5=A4=8DPmpAccessFaultHandle?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=88=A4=E6=96=AD=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c b/Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c index 3c967f409..2cabdb2c9 100644 --- a/Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c +++ b/Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c @@ -327,7 +327,7 @@ x_bool PmpAccessFaultHandle(void *task_pmp, x_ubase addr) __swap: - if ( region_type = PMP_TOR ) { + if ( region_type == PMP_TOR ) { if( pmp->count < PMP_MAX_ENTRY_NUMBER - 2) { DoubleLinkListRmNode(&(tor_node->link)); DoubleLinkListInsertNodeBefore(&pmp->tor_list, &tor_node->link); @@ -340,9 +340,7 @@ __swap: DoubleLinkListInsertNodeBefore(&pmp->tor_list, &tor_node->link); DoubleLinkListInsertNodeBefore(&pmp->tor_swap_list, &swap_node->link); swap_node->swap_count ++; - } - } ret = RET_TRUE; -- 2.34.1 From c39f55325f4830ef4cba94bd20d6868020068e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=9A=E7=A5=96=E6=9C=9B?= <5171267+gongzuwang@user.noreply.gitee.com> Date: Fri, 15 May 2026 10:26:43 +0800 Subject: [PATCH 3/9] =?UTF-8?q?region=5Ftype=E6=98=BE=E7=A4=BA=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c b/Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c index 2cabdb2c9..71cbebebf 100644 --- a/Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c +++ b/Ubiquitous/XiZi_IIoT_Macro/arch/risc-v/shared/pmp.c @@ -308,7 +308,7 @@ x_bool PmpAccessFaultHandle(void *task_pmp, x_ubase addr) pmp = (struct Pmp *)task_pmp ; x_bool ret = RET_FALSE; - uint8_t region_type; + uint8_t region_type = 0; DoubleLinklistType *link = NONE; struct PmpRegionTor *tor_node = NONE; -- 2.34.1 From aa6318d60f90fc0aca0c5ced5427e784969e65dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=9A=E7=A5=96=E6=9C=9B?= <5171267+gongzuwang@user.noreply.gitee.com> Date: Tue, 19 May 2026 10:39:03 +0800 Subject: [PATCH 4/9] fix(kernel): close semaphore lookup/use race (use-after-free) --- .../XiZi_IIoT_Macro/kernel/include/xs_sem.h | 8 +- .../XiZi_IIoT_Macro/kernel/thread/semaphore.c | 125 +++++++----------- 2 files changed, 54 insertions(+), 79 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT_Macro/kernel/include/xs_sem.h b/Ubiquitous/XiZi_IIoT_Macro/kernel/include/xs_sem.h index e7cae4f42..d3e6a93e6 100644 --- a/Ubiquitous/XiZi_IIoT_Macro/kernel/include/xs_sem.h +++ b/Ubiquitous/XiZi_IIoT_Macro/kernel/include/xs_sem.h @@ -41,10 +41,10 @@ struct Semaphore typedef struct { int32 (*SemaphoreCreate)(uint16 val); - void (*SemaphoreDelete)(struct Semaphore *sem); - int32 (*SemaphoreObtain)(struct Semaphore *sem, int32 wait_time); - int32 (*SemaphoreAbandon)(struct Semaphore *sem); - int32 (*SemaphoreSetValue)(struct Semaphore *sem, uint16 val); + void (*SemaphoreDelete)(int32 id); + int32 (*SemaphoreObtain)(int32 id, int32 wait_time); + int32 (*SemaphoreAbandon)(int32 id); + int32 (*SemaphoreSetValue)(int32 id, uint16 val); } SemaphoreDoneType; int32 KSemaphoreCreate(uint16 val); diff --git a/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/semaphore.c b/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/semaphore.c index 54ff78629..8a461aa88 100644 --- a/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/semaphore.c +++ b/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/semaphore.c @@ -61,15 +61,25 @@ static int32 _SemaphoreCreate(uint16 val) return id; } -static void _SemaphoreDelete(struct Semaphore *sem) +static void _SemaphoreDelete(int32 id) { int resched = 0; x_base lock = 0; + struct Semaphore *sem = NONE; + struct IdNode *idnode = NONE; - NULL_PARAM_CHECK(sem); + if (id < 0) + return; + + lock = CriticalAreaLock(); + idnode = IdGetObj(&k_sem_id_manager, id); + if (idnode == NONE) { + CriticalAreaUnLock(lock); + return; + } + sem = CONTAINER_OF(idnode, struct Semaphore, id); SYS_KDEBUG_LOG(KDBG_IPC, ("deleted semaphore: id %d\n", (int)sem->id.id)); - lock = CriticalAreaLock(); if (!IsDoubleLinkListEmpty(&sem->pend_list)) { resched = 1; LinklistResumeAll(&sem->pend_list); @@ -84,21 +94,29 @@ static void _SemaphoreDelete(struct Semaphore *sem) if (resched){ DO_KTASK_ASSIGN; } - } -static int32 _SemaphoreObtain(struct Semaphore *sem, int32 msec) +static int32 _SemaphoreObtain(int32 id, int32 msec) { int lock = 0; int32 wait_time = 0; struct TaskDescriptor *task = NONE; + struct Semaphore *sem = NONE; + struct IdNode *idnode = NONE; - NULL_PARAM_CHECK(sem); + if (id < 0) + return -ERROR; if(WAITING_FOREVER == msec) wait_time = WAITING_FOREVER; else wait_time = CalculateTickFromTimeMs(msec); lock = CriticalAreaLock(); + idnode = IdGetObj(&k_sem_id_manager, id); + if (idnode == NONE) { + CriticalAreaUnLock(lock); + return -ERROR; + } + sem = CONTAINER_OF(idnode, struct Semaphore, id); SYS_KDEBUG_LOG(KDBG_IPC, ("obtain semaphore: id %d, value %d, by task %s\n", (int)sem->id.id, (int)sem->value, GetKTaskDescriptor()->task_base_info.name)); @@ -134,14 +152,23 @@ static int32 _SemaphoreObtain(struct Semaphore *sem, int32 msec) return task->exstatus; } -static int32 _SemaphoreAbandon(struct Semaphore *sem) +static int32 _SemaphoreAbandon(int32 id) { int lock = 0; int resched = 0; + struct Semaphore *sem = NONE; + struct IdNode *idnode = NONE; - NULL_PARAM_CHECK(sem); + if (id < 0) + return -ERROR; lock = CriticalAreaLock(); + idnode = IdGetObj(&k_sem_id_manager, id); + if (idnode == NONE) { + CriticalAreaUnLock(lock); + return -ERROR; + } + sem = CONTAINER_OF(idnode, struct Semaphore, id); SYS_KDEBUG_LOG(KDBG_IPC, ("abandon semaphore: id %d, value %d, by task %s\n", (int)sem->id.id, (int)sem->value, GetKTaskDescriptor()->task_base_info.name)); @@ -162,14 +189,23 @@ static int32 _SemaphoreAbandon(struct Semaphore *sem) return EOK; } -static int32 _SemaphoreSetValue(struct Semaphore *sem, uint16 val) +static int32 _SemaphoreSetValue(int32 id, uint16 val) { int lock = 0; int resched = 0; + struct Semaphore *sem = NONE; + struct IdNode *idnode = NONE; - NULL_PARAM_CHECK(sem); + if (id < 0) + return -ERROR; lock = CriticalAreaLock(); + idnode = IdGetObj(&k_sem_id_manager, id); + if (idnode == NONE) { + CriticalAreaUnLock(lock); + return -ERROR; + } + sem = CONTAINER_OF(idnode, struct Semaphore, id); SYS_KDEBUG_LOG(KDBG_IPC, ("set semaphore value: id %d, old value %d, new value %d, by task %s\n", (int)sem->id.id, (int)sem->value, (int)val, GetKTaskDescriptor()->task_base_info.name)); @@ -221,24 +257,9 @@ int32 KSemaphoreCreate(uint16 val) */ void KSemaphoreDelete(int32 id) { - x_base lock = 0; - struct Semaphore *sem = NONE; - struct IdNode *idnode = NONE; - KDEBUG_NOT_IN_INTERRUPT; - if (id < 0) - return; - lock = CriticalAreaLock(); - idnode = IdGetObj(&k_sem_id_manager, id); - if (idnode == NONE){ - CriticalAreaUnLock(lock); - return; - } - CriticalAreaUnLock(lock); - - sem = CONTAINER_OF(idnode, struct Semaphore, id); - done.SemaphoreDelete(sem); + done.SemaphoreDelete(id); } /** @@ -252,22 +273,7 @@ int32 KSemaphoreObtain(int32 id, int32 msec) { KDEBUG_NOT_IN_INTERRUPT; - x_base lock = 0; - struct Semaphore *sem = NONE; - struct IdNode *idnode = NONE; - - if (id < 0) - return -ERROR; - lock = CriticalAreaLock(); - idnode = IdGetObj(&k_sem_id_manager, id); - if (idnode == NONE){ - CriticalAreaUnLock(lock); - return -ERROR; - } - - sem =CONTAINER_OF(idnode, struct Semaphore, id); - CriticalAreaUnLock(lock); - return done.SemaphoreObtain(sem, msec); + return done.SemaphoreObtain(id, msec); } /** @@ -280,23 +286,7 @@ int32 KSemaphoreAbandon(int32 id) { KDEBUG_NOT_IN_INTERRUPT; - x_base lock = 0; - struct Semaphore *sem = NONE; - struct IdNode *idnode = NONE; - - if (id < 0) - return -ERROR; - lock = CriticalAreaLock(); - idnode = IdGetObj(&k_sem_id_manager, id); - if (idnode == NONE) { - CriticalAreaUnLock(lock); - return -ERROR; - } - - sem =CONTAINER_OF(idnode, struct Semaphore, id); - CriticalAreaUnLock(lock); - - return done.SemaphoreAbandon(sem); + return done.SemaphoreAbandon(id); } /** @@ -310,20 +300,5 @@ int32 KSemaphoreSetValue(int32 id, uint16 val) { KDEBUG_NOT_IN_INTERRUPT; - x_base lock = 0; - struct Semaphore *sem = NONE; - struct IdNode *idnode = NONE; - - if (id < 0) - return -ERROR; - lock = CriticalAreaLock(); - idnode = IdGetObj(&k_sem_id_manager, id); - if (idnode == NONE) { - CriticalAreaUnLock(lock); - return -ERROR; - } - - sem = CONTAINER_OF(idnode, struct Semaphore, id); - CriticalAreaUnLock(lock); - return done.SemaphoreSetValue(sem, val); + return done.SemaphoreSetValue(id, val); } -- 2.34.1 From 8af1e056560d2ac019e2d2ab5ee76b46c7306098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=9A=E7=A5=96=E6=9C=9B?= <5171267+gongzuwang@user.noreply.gitee.com> Date: Tue, 19 May 2026 11:28:53 +0800 Subject: [PATCH 5/9] fix(kernel): use cached height for AVL tree instead of recursive scan --- .../XiZi_IIoT_Macro/kernel/thread/avl_tree.c | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/avl_tree.c b/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/avl_tree.c index 6b291fa24..7e6b0ea4a 100644 --- a/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/avl_tree.c +++ b/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/avl_tree.c @@ -29,14 +29,23 @@ * This function will return the node height of the avl tree * * @param avl_node avl tree node descriptor - * @return 0 + * @return cached height, or 0 if node is NULL */ static uint32 AvlTreeGetNodeHeight(AvlNodeType avl_node) +{ + return avl_node ? avl_node->height : 0; +} + +/** + * This function will update the cached height of the avl tree node + * + * @param avl_node avl tree node descriptor + */ +static void AvlTreeUpdateNodeHeight(AvlNodeType avl_node) { if(avl_node) { - return AVL_MAX(AvlTreeGetNodeHeight(avl_node->left), AvlTreeGetNodeHeight(avl_node->right)) + 1; - } else { - return 0; + avl_node->height = AVL_MAX(AvlTreeGetNodeHeight(avl_node->left), + AvlTreeGetNodeHeight(avl_node->right)) + 1; } } @@ -69,8 +78,8 @@ static AvlNodeType AvlTreeSetRightRotate(AvlNodeType avl_node) avl_node->left = new_node->right; new_node->right = avl_node; - new_node->height = AVL_MAX(AvlTreeGetNodeHeight(new_node->left), AvlTreeGetNodeHeight(new_node->right)) + 1; - avl_node->height = AVL_MAX(AvlTreeGetNodeHeight(avl_node->left), AvlTreeGetNodeHeight(avl_node->right)) + 1; + AvlTreeUpdateNodeHeight(avl_node); + AvlTreeUpdateNodeHeight(new_node); return new_node; } @@ -90,8 +99,8 @@ static AvlNodeType AvlTreeSetLeftRotate(AvlNodeType avl_node) avl_node->right = new_node->left; new_node->left = avl_node; - new_node->height = AVL_MAX(AvlTreeGetNodeHeight(new_node->left), AvlTreeGetNodeHeight(new_node->right)) + 1; - avl_node->height = AVL_MAX(AvlTreeGetNodeHeight(avl_node->left), AvlTreeGetNodeHeight(avl_node->right)) + 1; + AvlTreeUpdateNodeHeight(avl_node); + AvlTreeUpdateNodeHeight(new_node); return new_node; } @@ -221,6 +230,7 @@ AvlNodeType AvlTreeInsertNode(AvlNodeType avl_node, int32 data) } } + AvlTreeUpdateNodeHeight(avl_node); return AvlTreeBalance(avl_node); } @@ -308,6 +318,7 @@ AvlNodeType AvlTreeDeleteNode(AvlNodeType avl_node, int32 data) } } + AvlTreeUpdateNodeHeight(avl_node); return AvlTreeBalance(avl_node); } else { KPrintf("AvlTreeDeleteNode cannot find the delete data\n"); -- 2.34.1 From 0f8d53f367c8a20fdcf24309f2c6ee6b6e1b3c1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=9A=E7=A5=96=E6=9C=9B?= <5171267+gongzuwang@user.noreply.gitee.com> Date: Tue, 19 May 2026 14:15:42 +0800 Subject: [PATCH 6/9] fix(kernel): correct AVL node deletion and memory free --- .../XiZi_IIoT_Macro/kernel/thread/avl_tree.c | 96 +++++-------------- 1 file changed, 26 insertions(+), 70 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/avl_tree.c b/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/avl_tree.c index 7e6b0ea4a..76d340e68 100644 --- a/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/avl_tree.c +++ b/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/avl_tree.c @@ -234,71 +234,6 @@ AvlNodeType AvlTreeInsertNode(AvlNodeType avl_node, int32 data) return AvlTreeBalance(avl_node); } -/** - * This function will find the pre node of the avl_node - * - * @param avl_node avl tree node descriptor - * @return avl tree node - */ -static AvlNodeType AvlTreeFindPreNode(AvlNodeType avl_node) -{ - NULL_PARAM_CHECK(avl_node); - - AvlNodeType pre_node = NONE; - - if(avl_node->left) { - if(avl_node->left->right) { - pre_node = avl_node->left->right; - while(pre_node->right) { - pre_node = pre_node->right; - } - } else { - pre_node = avl_node->left; - } - } else { - pre_node = avl_node; - } - - return pre_node; -} - -/** - * This function will delete a certain node, ultimate target is to find the leaf node - * - * @param avl_node avl tree node descriptor - * @param data delete data - * @return avl tree node - */ -static AvlNodeType AvlTreeDeleteLeafNode(AvlNodeType avl_node) -{ - AvlNodeType pre_node = NONE; - - if((NONE == avl_node->left) && (NONE == avl_node->right)) { - /*Leaf Node*/ - avl_node = NONE; - x_free(avl_node); - } else if(NONE == avl_node->left) { - /*Right child is Leaf Node*/ - avl_node->data = avl_node->right->data; - avl_node->right = NONE; - x_free(avl_node->right); - } else if(NONE == avl_node->right) { - /*Left child is Leaf Node*/ - avl_node->data = avl_node->left->data; - avl_node->left = NONE; - x_free(avl_node->left); - } else { - /*Find the pre node to replace the avl node, then delete the pre node*/ - pre_node = AvlTreeFindPreNode(avl_node); - if(pre_node) { - avl_node->data = pre_node->data; - avl_node->left = AvlTreeDeleteNode(avl_node->left, pre_node->data); - } - } - - return avl_node; -} - /** * This function will delete data from the avl tree * @@ -307,14 +242,35 @@ static AvlNodeType AvlTreeDeleteLeafNode(AvlNodeType avl_node) */ AvlNodeType AvlTreeDeleteNode(AvlNodeType avl_node, int32 data) { + AvlNodeType temp = NONE; + AvlNodeType pred = NONE; + if(avl_node) { - if(data == avl_node->data) { - avl_node = AvlTreeDeleteLeafNode(avl_node); + if(avl_node->data < data) { + avl_node->right = AvlTreeDeleteNode(avl_node->right, data); + } else if(avl_node->data > data) { + avl_node->left = AvlTreeDeleteNode(avl_node->left, data); } else { - if(avl_node->data < data) { - avl_node->right = AvlTreeDeleteNode(avl_node->right, data); + if((NONE == avl_node->left) && (NONE == avl_node->right)) { + x_free(avl_node); + return NONE; + } else if(NONE == avl_node->left) { + temp = avl_node->right; + x_free(avl_node); + AvlTreeUpdateNodeHeight(temp); + return AvlTreeBalance(temp); + } else if(NONE == avl_node->right) { + temp = avl_node->left; + x_free(avl_node); + AvlTreeUpdateNodeHeight(temp); + return AvlTreeBalance(temp); } else { - avl_node->left = AvlTreeDeleteNode(avl_node->left, data); + pred = avl_node->left; + while(pred->right) { + pred = pred->right; + } + avl_node->data = pred->data; + avl_node->left = AvlTreeDeleteNode(avl_node->left, pred->data); } } -- 2.34.1 From 7008ab06b386d5ca221446b96ad537f056a80cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=9A=E7=A5=96=E6=9C=9B?= <5171267+gongzuwang@user.noreply.gitee.com> Date: Tue, 19 May 2026 14:32:10 +0800 Subject: [PATCH 7/9] fix(kernel): reject InitMemGather when pool cannot fit any block --- .../XiZi_IIoT_Macro/kernel/memory/gatherblock.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT_Macro/kernel/memory/gatherblock.c b/Ubiquitous/XiZi_IIoT_Macro/kernel/memory/gatherblock.c index 6ac255725..bea23e086 100644 --- a/Ubiquitous/XiZi_IIoT_Macro/kernel/memory/gatherblock.c +++ b/Ubiquitous/XiZi_IIoT_Macro/kernel/memory/gatherblock.c @@ -53,6 +53,11 @@ x_err_t InitMemGather(struct MemGather *gm_handler, const char *gm_name, void * CHECK(gm_size >= 1 && one_block_size >= 1); + if (ALIGN_MEN_DOWN(gm_size, MEM_ALIGN_SIZE) < + ALIGN_MEN_UP(one_block_size, MEM_ALIGN_SIZE) + sizeof(uint8 *)) { + return ERROR; + } + lock = CriticalAreaLock(); /* try to find gatherblock object */ @@ -97,8 +102,10 @@ x_err_t InitMemGather(struct MemGather *gm_handler, const char *gm_name, void * (uint8 *)(block_ptr + (off_block + 1) * (one_block_size + sizeof(uint8 *))); } - *(uint8 **)(block_ptr + (off_block - 1) * (one_block_size + sizeof(uint8 *))) = - NONE; + if (gm_handler->block_total_number > 0) { + *(uint8 **)(block_ptr + (off_block - 1) * (one_block_size + sizeof(uint8 *))) = + NONE; + } gm_handler->m_block_link = block_ptr; -- 2.34.1 From 37c97ce2eba51c93a3316d0a1a9b0f14279f0036 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=9A=E7=A5=96=E6=9C=9B?= <5171267+gongzuwang@user.noreply.gitee.com> Date: Tue, 19 May 2026 14:47:20 +0800 Subject: [PATCH 8/9] fix(kernel): reject MemGather delete while blocks are still allocated --- .../XiZi_IIoT_Macro/kernel/include/xs_memory.h | 1 + .../XiZi_IIoT_Macro/kernel/memory/gatherblock.c | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT_Macro/kernel/include/xs_memory.h b/Ubiquitous/XiZi_IIoT_Macro/kernel/include/xs_memory.h index 17ffea9bc..14c974da0 100644 --- a/Ubiquitous/XiZi_IIoT_Macro/kernel/include/xs_memory.h +++ b/Ubiquitous/XiZi_IIoT_Macro/kernel/include/xs_memory.h @@ -78,6 +78,7 @@ struct MemGather typedef struct MemGather *GatherMemType; x_err_t InitMemGather(struct MemGather *gm_handler, const char *gm_name, void *begin_address, x_size_t gm_size, x_size_t one_block_size); +/* Caller must FreeBlockMemGather all blocks before RemoveMemGather/DeleteMemGather. */ x_err_t RemoveMemGather(struct MemGather *gm_handler); GatherMemType CreateMemGather(const char *gm_name, x_size_t block_number, x_size_t one_block_size); x_err_t DeleteMemGather(GatherMemType gm_handler); diff --git a/Ubiquitous/XiZi_IIoT_Macro/kernel/memory/gatherblock.c b/Ubiquitous/XiZi_IIoT_Macro/kernel/memory/gatherblock.c index bea23e086..95b439700 100644 --- a/Ubiquitous/XiZi_IIoT_Macro/kernel/memory/gatherblock.c +++ b/Ubiquitous/XiZi_IIoT_Macro/kernel/memory/gatherblock.c @@ -115,11 +115,12 @@ x_err_t InitMemGather(struct MemGather *gm_handler, const char *gm_name, void * /** - * This function will remove the gatherblock from the global list, which is created by MemGatherInit function + * This function will remove the gatherblock from the global list, which is created by MemGatherInit function. + * All blocks must be returned via FreeBlockMemGather before calling this function. * * @param gm_handler the gatherblock to be removed * - * @return EOK + * @return EOK on success; ERROR if blocks are still allocated */ x_err_t RemoveMemGather(struct MemGather *gm_handler) { @@ -131,6 +132,10 @@ x_err_t RemoveMemGather(struct MemGather *gm_handler) CHECK((gm_handler->m_kind & Cmpt_KindN_Static)!=0); + if (gm_handler->block_free_number != gm_handler->block_total_number) { + return ERROR; + } + /* resume all the suspend tasks on gatherblock object */ while (!IsDoubleLinkListEmpty(&(gm_handler->wait_task))) { critical_value = CriticalAreaLock(); @@ -245,10 +250,11 @@ GatherMemType CreateMemGather(const char *gm_name, x_size_t block_number, x_size /** * This function will delete a gatherblock object, which is created by MemGatherCreate function. + * All blocks must be returned via FreeBlockMemGather before calling this function. * * @param gm_handler the gatherblock object to be deleted * - * @return EOK + * @return EOK on success; ERROR if blocks are still allocated */ x_err_t DeleteMemGather(GatherMemType gm_handler) { @@ -261,6 +267,10 @@ x_err_t DeleteMemGather(GatherMemType gm_handler) NULL_PARAM_CHECK(gm_handler); CHECK(((gm_handler->m_kind & Cmpt_KindN_Static)==0)); + if (gm_handler->block_free_number != gm_handler->block_total_number) { + return ERROR; + } + /* resume all the suspend tasks on gatherblock object */ while (!IsDoubleLinkListEmpty(&(gm_handler->wait_task))) { critical_value = CriticalAreaLock(); -- 2.34.1 From b63d5b2b1f41c4c2577bea905cce2b1472c7fb8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=9A=E7=A5=96=E6=9C=9B?= <5171267+gongzuwang@user.noreply.gitee.com> Date: Tue, 19 May 2026 14:55:38 +0800 Subject: [PATCH 9/9] fix(kernel): wake recv waiters in MsgQueue urgent send --- Ubiquitous/XiZi_IIoT_Macro/kernel/thread/msgqueue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/msgqueue.c b/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/msgqueue.c index 3f581619e..e4f9a63dd 100644 --- a/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/msgqueue.c +++ b/Ubiquitous/XiZi_IIoT_Macro/kernel/thread/msgqueue.c @@ -183,8 +183,8 @@ static x_err_t _MsgQueueUrgentSend(struct MsgQueue *mq, const void *buffer, x_si msg = mq->msg_buf + (mq->index % mq->max_msgs) * mq->each_len; memcpy(msg , buffer, size); mq->num_msgs ++; - if (!IsDoubleLinkListEmpty(&mq->send_pend_list)) { - LinklistResume(&(mq->send_pend_list)); + if (!IsDoubleLinkListEmpty(&mq->recv_pend_list)) { + LinklistResume(&(mq->recv_pend_list)); CriticalAreaUnLock(lock); DO_KTASK_ASSIGN; return EOK; -- 2.34.1