sched/pthread: check pthread group and flags before join

Prevent users from using the wrong pid and causing system crash.

Signed-off-by: zhangyuan21 <zhangyuan21@xiaomi.com>
This commit is contained in:
zhangyuan21 2023-01-13 21:38:00 +08:00 committed by Xiang Xiao
parent fb12b6e3a9
commit 9fd30c7f63
2 changed files with 11 additions and 4 deletions

View File

@ -140,7 +140,8 @@ FAR struct join_s *pthread_findjoininfo(FAR struct task_group_s *group,
{ {
FAR struct tcb_s *tcb = nxsched_get_tcb((pthread_t)pid); FAR struct tcb_s *tcb = nxsched_get_tcb((pthread_t)pid);
if (tcb != NULL && (tcb->flags & TCB_FLAG_DETACHED) == 0) if (tcb != NULL && (tcb->flags & TCB_FLAG_DETACHED) == 0 &&
(tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_PTHREAD)
{ {
pjoin = pthread_createjoininfo((FAR struct pthread_tcb_s *)tcb); pjoin = pthread_createjoininfo((FAR struct pthread_tcb_s *)tcb);
} }

View File

@ -75,6 +75,7 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value)
FAR struct tcb_s *rtcb = this_task(); FAR struct tcb_s *rtcb = this_task();
FAR struct task_group_s *group = rtcb->group; FAR struct task_group_s *group = rtcb->group;
FAR struct join_s *pjoin; FAR struct join_s *pjoin;
FAR struct tcb_s *tcb;
int ret; int ret;
sinfo("thread=%d group=%p\n", thread, group); sinfo("thread=%d group=%p\n", thread, group);
@ -84,11 +85,18 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value)
enter_cancellation_point(); enter_cancellation_point();
tcb = nxsched_get_tcb(thread);
if (tcb != NULL && tcb->group != group)
{
leave_cancellation_point();
return EINVAL;
}
/* First make sure that this is not an attempt to join to /* First make sure that this is not an attempt to join to
* ourself. * ourself.
*/ */
if ((pid_t)thread == gettid()) if (tcb == rtcb)
{ {
leave_cancellation_point(); leave_cancellation_point();
return EDEADLK; return EDEADLK;
@ -114,8 +122,6 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value)
{ {
/* Determine what kind of error to return */ /* Determine what kind of error to return */
FAR struct tcb_s *tcb = nxsched_get_tcb((pthread_t)thread);
swarn("WARNING: Could not find thread data\n"); swarn("WARNING: Could not find thread data\n");
/* Case (1) or (3) -- we can't tell which. Assume (3) */ /* Case (1) or (3) -- we can't tell which. Assume (3) */