Skip to content

Commit 108a3e6

Browse files
committed
sched/group: skip group_release for kernel thread group
When CONFIG_DISABLE_PTHREAD=y, HAVE_GROUP_MEMBERS is undefined and group_leave() unconditionally calls group_release() for every exiting thread. This destroys the shared g_kthread_group resources (mutex, fdlist, task_info) while other kernel threads are still using them, causing use-after-free crashes. Fix by checking TCB_FLAG_TTYPE_KERNEL in group_leave() before calling group_release(), so the entire release path is skipped for kernel threads. This is safe because g_kthread_group is statically allocated and its lifetime is the entire system. Signed-off-by: wangyongrong <wangyongrong@xiaomi.com>
1 parent 3759cc7 commit 108a3e6

2 files changed

Lines changed: 7 additions & 4 deletions

File tree

include/nuttx/sched.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@
118118
#define GROUP_FLAG_DELETED (1 << 2) /* Bit 2: Group has been deleted but not yet freed */
119119
#define GROUP_FLAG_EXITING (1 << 3) /* Bit 3: Group exit is in progress */
120120
#define GROUP_FLAG_FD_BACKTRACE (1 << 4) /* Bit 4: Enable FD backtrace for the group */
121-
/* Bits 3-7: Available */
121+
/* Bits 5-7: Available */
122122

123123
/* Values for struct child_status_s ch_flags */
124124

sched/group/group_leave.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
* Release group resources after the last member has left the group.
6060
*
6161
* Input Parameters:
62-
* group - The group to be removed.
62+
* group - The group to be released.
6363
*
6464
* Returned Value:
6565
* None.
@@ -173,17 +173,20 @@ void group_leave(FAR struct tcb_s *tcb)
173173
group = tcb->group;
174174
if (group)
175175
{
176+
bool release = !(atomic_read(&tcb->flags) & TCB_FLAG_TTYPE_KERNEL);
177+
176178
/* Remove the member from group. */
177179

178180
#ifdef HAVE_GROUP_MEMBERS
179181
flags = spin_lock_irqsave(&group->tg_lock);
180182
sq_rem(&tcb->member, &group->tg_members);
183+
release = release && sq_empty(&group->tg_members);
181184
spin_unlock_irqrestore(&group->tg_lock, flags);
182185

183186
/* Have all of the members left the group? */
184-
185-
if (sq_empty(&group->tg_members))
186187
#endif
188+
189+
if (release)
187190
{
188191
/* Yes.. Release all of the resource held by the task group */
189192

0 commit comments

Comments
 (0)