forked from nuttx/nuttx-update
waitpid: CRITICAL BUGFIX. Add a reference counting mechansim to prevent wait from using stale memory that was freed by the exiting task
This commit is contained in:
parent
8f540fd81a
commit
b90da3f27b
13 changed files with 44 additions and 85 deletions
|
@ -11244,4 +11244,7 @@
|
|||
Entinger (2015-12-15).
|
||||
* configs/launchxl-tms57004: Add basic board support for TI LaunchXL-
|
||||
TMS57004. Not much to see there yet (2015-12-15).
|
||||
* waitpid: CRITICAL BUGFIX. Add a reference count to prevent waitpid
|
||||
from using stale memory released by the waited-for task group
|
||||
(2015-12-22).
|
||||
|
||||
|
|
2
arch
2
arch
|
@ -1 +1 @@
|
|||
Subproject commit a8666b5bb6841d514d1fccedb0071df38d78217a
|
||||
Subproject commit 1519d53e182663632e4b115baa1b3b15ce9840a3
|
2
configs
2
configs
|
@ -1 +1 @@
|
|||
Subproject commit 196f9f3f3f067ccb3c285078a704a2a5eb37b7ea
|
||||
Subproject commit b30cbace6afab3caed2dcfec09071af60a2b0d7f
|
|
@ -154,6 +154,7 @@
|
|||
#define GROUP_FLAG_NOCLDWAIT (1 << 0) /* Bit 0: Do not retain child exit status */
|
||||
#define GROUP_FLAG_ADDRENV (1 << 1) /* Bit 1: Group has an address environment */
|
||||
#define GROUP_FLAG_PRIVILEGED (1 << 2) /* Bit 2: Group is privileged */
|
||||
#define GROUP_FLAG_DELETED (1 << 3) /* Bit 3: Group has been deleted but not yet freed */
|
||||
|
||||
/* Values for struct child_status_s ch_flags */
|
||||
|
||||
|
@ -418,6 +419,7 @@ struct task_group_s
|
|||
/* waitpid support ************************************************************/
|
||||
/* Simple mechanism used only when there is no support for SIGCHLD */
|
||||
|
||||
uint8_t tg_nwaiters; /* Number of waiters */
|
||||
sem_t tg_exitsem; /* Support for waitpid */
|
||||
int *tg_statloc; /* Location to return exit status */
|
||||
#endif
|
||||
|
|
|
@ -44,14 +44,6 @@
|
|||
|
||||
#include <nuttx/mm/mm.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
|
|
@ -43,10 +43,6 @@
|
|||
|
||||
#include <nuttx/mm/mm.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
|
|
@ -42,6 +42,10 @@ CSRCS += task_reparent.c
|
|||
ifeq ($(CONFIG_SCHED_CHILD_STATUS),y)
|
||||
CSRCS += group_childstatus.c
|
||||
endif
|
||||
else
|
||||
ifeq ($(CONFIG_SCHED_WAITPID),y)
|
||||
CSRCS += group_waiter.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_ADDRENV),y)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* sched/group/group.h
|
||||
*
|
||||
* Copyright (C) 2007-2013 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2013, 2015 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -102,6 +102,10 @@ int group_bind(FAR struct pthread_tcb_s *tcb);
|
|||
int group_join(FAR struct pthread_tcb_s *tcb);
|
||||
#endif
|
||||
void group_leave(FAR struct tcb_s *tcb);
|
||||
#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT)
|
||||
void group_addwaiter(FAR struct task_group_s *group);
|
||||
void group_delwaiter(FAR struct task_group_s *group);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
|
||||
FAR struct task_group_s *group_findbygid(gid_t gid);
|
||||
|
|
|
@ -50,26 +50,6 @@
|
|||
#if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \
|
||||
defined(CONFIG_MM_KERNEL_HEAP)
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -100,7 +80,7 @@ void group_free(FAR struct task_group_s *group, FAR void *mem)
|
|||
{
|
||||
/* It is a privileged group... use the kernel mode memory allocator */
|
||||
|
||||
return kmm_free(mem);
|
||||
kmm_free(mem);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -108,7 +88,7 @@ void group_free(FAR struct task_group_s *group, FAR void *mem)
|
|||
* allocator.
|
||||
*/
|
||||
|
||||
return kumm_free(mem);
|
||||
kumm_free(mem);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
* sched/group/group_leave.c
|
||||
*
|
||||
* Copyright (C) 2013-2014 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2013-2015 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -56,18 +56,6 @@
|
|||
|
||||
#ifdef HAVE_TASK_GROUP
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
@ -271,9 +259,23 @@ static inline void group_release(FAR struct task_group_s *group)
|
|||
# endif
|
||||
#endif
|
||||
|
||||
/* Release the group container itself */
|
||||
#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT)
|
||||
/* If there are threads waiting for this group to be freed, then we cannot
|
||||
* yet free the memory resources. Instead just mark the group deleted
|
||||
* and wait for those threads complete their waits.
|
||||
*/
|
||||
|
||||
sched_kfree(group);
|
||||
if (group->tg_nwaiters > 0)
|
||||
{
|
||||
group->tg_flags |= GROUP_FLAG_DELETED;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Release the group container itself */
|
||||
|
||||
sched_kfree(group);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -51,10 +51,6 @@
|
|||
|
||||
#ifdef CONFIG_SCHED_WAITPID
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -217,6 +213,10 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options)
|
|||
group = ctcb->group;
|
||||
DEBUGASSERT(group);
|
||||
|
||||
/* Lock this group so that it cannot be deleted until the wait completes */
|
||||
|
||||
group_addwaiter(group);
|
||||
|
||||
/* "If more than one thread is suspended in waitpid() awaiting termination of
|
||||
* the same process, exactly one thread will return the process status at the
|
||||
* time of the target process termination." Hmmm.. what do we return to the
|
||||
|
@ -236,6 +236,8 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options)
|
|||
/* Don't wait if status is not available */
|
||||
|
||||
ret = sem_trywait(&group->tg_exitsem);
|
||||
group_delwaiter(group);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
pid = 0;
|
||||
|
@ -246,6 +248,8 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options)
|
|||
/* Wait if necessary for status to become available */
|
||||
|
||||
ret = sem_wait(&group->tg_exitsem);
|
||||
group_delwaiter(group);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
/* Unlock pre-emption and return the ERROR (sem_wait has already set
|
||||
|
|
|
@ -68,11 +68,7 @@ typedef int (*holderhandler_t)(FAR struct semholder_s *pholder,
|
|||
FAR sem_t *sem, FAR void *arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Preallocated holder structures */
|
||||
|
@ -82,10 +78,6 @@ static struct semholder_s g_holderalloc[CONFIG_SEM_PREALLOCHOLDERS];
|
|||
static FAR struct semholder_s *g_freeholders;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sem_allocholder
|
||||
****************************************************************************/
|
||||
|
|
|
@ -48,26 +48,6 @@
|
|||
#include "sched/sched.h"
|
||||
#include "semaphore/semaphore.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
|
Loading…
Reference in a new issue