sched/mqueue/mq_desclose.c: Add a test to verify that message queue is closed by the same task group that opened it. If not, then list corruption would result. This test is only performed if CONFIG_DEBUG_FEATURES is enabled since it should not normally be an issue: It would be a strange programming practice to open a message queue in open task group, then close it in another.

This commit is contained in:
김정찬 2019-08-05 18:30:07 -06:00 committed by Gregory Nutt
parent 721994846c
commit a12f80fb90
3 changed files with 48 additions and 12 deletions

View File

@ -77,6 +77,7 @@ int nxmq_close_group(mqd_t mqdes, FAR struct task_group_s *group)
{
FAR struct mqueue_inode_s *msgq;
FAR struct inode *inode;
int ret = OK;
DEBUGASSERT(mqdes != NULL && group != NULL);
@ -93,8 +94,9 @@ int nxmq_close_group(mqd_t mqdes, FAR struct task_group_s *group)
/* Close/free the message descriptor */
nxmq_desclose_group(mqdes, group);
ret = nxmq_desclose_group(mqdes, group);
if (ret >= 0)
{
/* Get the inode from the message queue structure */
inode = msgq->inode;
@ -103,10 +105,12 @@ int nxmq_close_group(mqd_t mqdes, FAR struct task_group_s *group)
/* Decrement the reference count on the inode, possibly freeing it */
mq_inode_release(inode);
}
sched_unlock();
}
return OK;
return ret;
}
/****************************************************************************

View File

@ -390,14 +390,15 @@ int nxmq_close_group(mqd_t mqdes, FAR struct task_group_s *group);
* group - Group that has the open descriptor.
*
* Returned Value:
* None.
* Zero (OK) is returned on success; a negated errno value is returned on
* and failure.
*
* Assumptions:
* - Called only from mq_close() with the scheduler locked.
*
****************************************************************************/
void nxmq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group);
int nxmq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group);
#undef EXTERN
#ifdef __cplusplus

View File

@ -83,20 +83,50 @@
* group - Group that has the open descriptor.
*
* Returned Value:
* None.
* Zero (OK) is returned on success; a negated errno value is returned on
* and failure.
*
* Assumptions:
* - Called only from mq_close() with the scheduler locked.
*
****************************************************************************/
void nxmq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group)
int nxmq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group)
{
FAR struct mqueue_inode_s *msgq;
#ifdef CONFIG_DEBUG_FEATURES
mqd_t mq_ptr;
#endif
DEBUGASSERT(mqdes != NULL && group != NULL);
/* Remove the message descriptor from the current task's list of message
#ifdef CONFIG_DEBUG_FEATURES
/* Check that msgq is valid for closing. It must be owned by the current
* group. NOTE the call to sq_rem() below would corrupt the descriptor
* list if mqdes did not lie in the list.
*/
mq_ptr = (mqd_t)sq_peek(&group->tg_msgdesq);
while (mq_ptr)
{
if (mq_ptr == mqdes)
{
break;
}
mq_ptr = (mqd_t)sq_next(mq_ptr);
}
DEBUGASSERT(mq_ptr != NULL);
if (mq_ptr == NULL)
{
/* 'mqdes' does not lie in the group's list of message descriptors. */
return -EPERM;
}
#endif
/* Remove the message descriptor from the current group's list of message
* descriptors.
*/
@ -121,4 +151,5 @@ void nxmq_desclose_group(mqd_t mqdes, FAR struct task_group_s *group)
/* Deallocate the message descriptor */
mq_desfree(mqdes);
return OK;
}