From a12f80fb900d20adcb46f172b09967490bce48cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=A0=95=EC=B0=AC?= Date: Mon, 5 Aug 2019 18:30:07 -0600 Subject: [PATCH] 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. --- fs/mqueue/mq_close.c | 18 +++++++++++------- include/nuttx/mqueue.h | 5 +++-- sched/mqueue/mq_desclose.c | 37 ++++++++++++++++++++++++++++++++++--- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/fs/mqueue/mq_close.c b/fs/mqueue/mq_close.c index 7647ccda7c..5f929057e8 100644 --- a/fs/mqueue/mq_close.c +++ b/fs/mqueue/mq_close.c @@ -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,20 +94,23 @@ 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 */ - /* Get the inode from the message queue structure */ + inode = msgq->inode; + DEBUGASSERT(inode->u.i_mqueue == msgq); - inode = msgq->inode; - DEBUGASSERT(inode->u.i_mqueue == msgq); + /* Decrement the reference count on the inode, possibly freeing it */ - /* Decrement the reference count on the inode, possibly freeing it */ + mq_inode_release(inode); + } - mq_inode_release(inode); sched_unlock(); } - return OK; + return ret; } /**************************************************************************** diff --git a/include/nuttx/mqueue.h b/include/nuttx/mqueue.h index f7a838335e..b0bb713ac7 100644 --- a/include/nuttx/mqueue.h +++ b/include/nuttx/mqueue.h @@ -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 diff --git a/sched/mqueue/mq_desclose.c b/sched/mqueue/mq_desclose.c index 09d10283fc..deab2ee708 100644 --- a/sched/mqueue/mq_desclose.c +++ b/sched/mqueue/mq_desclose.c @@ -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; }