From e7059f097428cf25035a28f73c83ed439926d208 Mon Sep 17 00:00:00 2001 From: chao an Date: Tue, 10 Jan 2023 17:54:49 +0800 Subject: [PATCH] sched/group: fix task info heap-use-after-free tg_info is still in use after task_uninit_info() unifies lib_stream_* with life cycle of task info to avoid this issue. |#10 0xf7abec89 in __asan::__asan_report_load2 (addr=4100993760) at ../../../../src/libsanitizer/asan/asan_rtl.cpp:119 |#11 0x5677356a in nxsem_destroy (sem=0xf47032e0) at semaphore/sem_destroy.c:73 |#12 0x56773695 in sem_destroy (sem=0xf47032e0) at semaphore/sem_destroy.c:120 |#13 0x5676faa2 in nxmutex_destroy (mutex=0xf47032e0) at include/nuttx/mutex.h:126 |#14 0x567a3430 in lib_stream_release (group=0xf4901ba0) at stdio/lib_libstream.c:98 |#15 0x5676da75 in group_release (group=0xf4901ba0) at group/group_leave.c:162 |#16 0x5676e51c in group_leave (tcb=0xf5377740) at group/group_leave.c:360 |#17 0x569fe79b in nxtask_exithook (tcb=0xf5377740, status=0) at task/task_exithook.c:455 |#18 0x569f90b9 in _exit (status=0) at task/exit.c:82 |#19 0x56742680 in exit (status=0) at stdlib/lib_exit.c:61 |#20 0x56a69c78 in iperf_showusage (progname=0xf2f28838 "iperf", exitcode=0) at iperf_main.c:91 |#21 0x56a6a6ec in iperf_main (argc=1, argv=0xf2f28830) at iperf_main.c:140 |#22 0x5679c148 in nxtask_startup (entrypt=0x56a69c78 , argc=1, argv=0xf2f28830) at sched/task_startup.c:70 |#23 0x56767f58 in nxtask_start () at task/task_start.c:134 Signed-off-by: chao an --- sched/group/group_create.c | 19 ++++++------------- sched/group/group_leave.c | 7 ------- sched/tls/task_initinfo.c | 7 +++++++ sched/tls/task_uninitinfo.c | 7 +++++++ 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/sched/group/group_create.c b/sched/group/group_create.c index fe7533629a61b..87727f84c0312 100644 --- a/sched/group/group_create.c +++ b/sched/group/group_create.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -165,14 +164,6 @@ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype) group->tg_mxmembers = GROUP_INITIAL_MEMBERS; #endif - /* Alloc task info for group */ - - ret = task_init_info(group); - if (ret < 0) - { - goto errout_with_member; - } - /* Attach the group to the TCB */ tcb->cmn.group = group; @@ -185,11 +176,13 @@ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype) files_initlist(&group->tg_filelist); -#ifdef CONFIG_FILE_STREAM - /* Initialize file streams for the task group */ + /* Alloc task info for group */ - lib_stream_initialize(group); -#endif + ret = task_init_info(group); + if (ret < 0) + { + goto errout_with_member; + } #ifndef CONFIG_DISABLE_PTHREAD /* Initialize the pthread join mutex */ diff --git a/sched/group/group_leave.c b/sched/group/group_leave.c index 2b1d11fdc0e33..309eeb9169ac6 100644 --- a/sched/group/group_leave.c +++ b/sched/group/group_leave.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #ifdef CONFIG_BINFMT_LOADABLE @@ -156,12 +155,6 @@ static inline void group_release(FAR struct task_group_s *group) pthread_release(group); #endif -#ifdef CONFIG_FILE_STREAM - /* Free resource held by the stream list */ - - lib_stream_release(group); -#endif /* CONFIG_FILE_STREAM */ - /* Free all file-related resources now. We really need to close files as * soon as possible while we still have a functioning task. */ diff --git a/sched/tls/task_initinfo.c b/sched/tls/task_initinfo.c index d7983b9197c32..88ded47c3d66b 100644 --- a/sched/tls/task_initinfo.c +++ b/sched/tls/task_initinfo.c @@ -26,6 +26,7 @@ #include #include +#include #include "tls.h" @@ -64,5 +65,11 @@ int task_init_info(FAR struct task_group_s *group) nxmutex_init(&info->ta_lock); group->tg_info = info; +#ifdef CONFIG_FILE_STREAM + /* Initialize file streams for the task group */ + + lib_stream_initialize(group); +#endif + return OK; } diff --git a/sched/tls/task_uninitinfo.c b/sched/tls/task_uninitinfo.c index 6c28b90559c37..42bf6c23e73cd 100644 --- a/sched/tls/task_uninitinfo.c +++ b/sched/tls/task_uninitinfo.c @@ -24,6 +24,7 @@ #include #include +#include #include "tls.h" @@ -49,6 +50,12 @@ void task_uninit_info(FAR struct task_group_s *group) { FAR struct task_info_s *info = group->tg_info; +#ifdef CONFIG_FILE_STREAM + /* Free resource held by the stream list */ + + lib_stream_release(group); +#endif /* CONFIG_FILE_STREAM */ + nxmutex_destroy(&info->ta_lock); group_free(group, info); }