mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 23:40:19 +08:00
sched/signal: add sanity check for siginfo
add sanity check for siginfo to ensure whether there is really a consumer waiting for the signal, since the task state will not be changed appropriately if in cancel/killed case Test Case: https://github.com/linux-test-project/ltp/blob/master/testcases/open_posix_testsuite/conformance/interfaces/sigpause/1-1.c#L63 Signed-off-by: chao an <anchao@lixiang.com>
This commit is contained in:
@@ -397,8 +397,12 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info)
|
|||||||
if (stcb->task_state == TSTATE_WAIT_SIG &&
|
if (stcb->task_state == TSTATE_WAIT_SIG &&
|
||||||
(masked == 0 ||
|
(masked == 0 ||
|
||||||
nxsig_ismember(&stcb->sigwaitmask, info->si_signo)))
|
nxsig_ismember(&stcb->sigwaitmask, info->si_signo)))
|
||||||
|
{
|
||||||
|
if (stcb->sigunbinfo != NULL)
|
||||||
{
|
{
|
||||||
memcpy(stcb->sigunbinfo, info, sizeof(siginfo_t));
|
memcpy(stcb->sigunbinfo, info, sizeof(siginfo_t));
|
||||||
|
}
|
||||||
|
|
||||||
sigemptyset(&stcb->sigwaitmask);
|
sigemptyset(&stcb->sigwaitmask);
|
||||||
|
|
||||||
if (WDOG_ISACTIVE(&stcb->waitdog))
|
if (WDOG_ISACTIVE(&stcb->waitdog))
|
||||||
@@ -460,8 +464,12 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (stcb->task_state == TSTATE_WAIT_SIG)
|
if (stcb->task_state == TSTATE_WAIT_SIG)
|
||||||
|
{
|
||||||
|
if (stcb->sigunbinfo != NULL)
|
||||||
{
|
{
|
||||||
memcpy(stcb->sigunbinfo, info, sizeof(siginfo_t));
|
memcpy(stcb->sigunbinfo, info, sizeof(siginfo_t));
|
||||||
|
}
|
||||||
|
|
||||||
sigemptyset(&stcb->sigwaitmask);
|
sigemptyset(&stcb->sigwaitmask);
|
||||||
|
|
||||||
if (WDOG_ISACTIVE(&stcb->waitdog))
|
if (WDOG_ISACTIVE(&stcb->waitdog))
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ static void nxsig_timeout(wdparm_t arg)
|
|||||||
{
|
{
|
||||||
FAR struct tcb_s *rtcb = this_task();
|
FAR struct tcb_s *rtcb = this_task();
|
||||||
|
|
||||||
|
if (wtcb->sigunbinfo != NULL)
|
||||||
|
{
|
||||||
wtcb->sigunbinfo->si_signo = SIG_WAIT_TIMEOUT;
|
wtcb->sigunbinfo->si_signo = SIG_WAIT_TIMEOUT;
|
||||||
wtcb->sigunbinfo->si_code = SI_TIMER;
|
wtcb->sigunbinfo->si_code = SI_TIMER;
|
||||||
wtcb->sigunbinfo->si_errno = ETIMEDOUT;
|
wtcb->sigunbinfo->si_errno = ETIMEDOUT;
|
||||||
@@ -107,6 +109,7 @@ static void nxsig_timeout(wdparm_t arg)
|
|||||||
wtcb->sigunbinfo->si_pid = 0; /* Not applicable */
|
wtcb->sigunbinfo->si_pid = 0; /* Not applicable */
|
||||||
wtcb->sigunbinfo->si_status = OK;
|
wtcb->sigunbinfo->si_status = OK;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove the task from waitting list */
|
/* Remove the task from waitting list */
|
||||||
|
|
||||||
@@ -166,6 +169,8 @@ void nxsig_wait_irq(FAR struct tcb_s *wtcb, int errcode)
|
|||||||
{
|
{
|
||||||
FAR struct tcb_s *rtcb = this_task();
|
FAR struct tcb_s *rtcb = this_task();
|
||||||
|
|
||||||
|
if (wtcb->sigunbinfo != NULL)
|
||||||
|
{
|
||||||
wtcb->sigunbinfo->si_signo = SIG_CANCEL_TIMEOUT;
|
wtcb->sigunbinfo->si_signo = SIG_CANCEL_TIMEOUT;
|
||||||
wtcb->sigunbinfo->si_code = SI_USER;
|
wtcb->sigunbinfo->si_code = SI_USER;
|
||||||
wtcb->sigunbinfo->si_errno = errcode;
|
wtcb->sigunbinfo->si_errno = errcode;
|
||||||
@@ -174,6 +179,7 @@ void nxsig_wait_irq(FAR struct tcb_s *wtcb, int errcode)
|
|||||||
wtcb->sigunbinfo->si_pid = 0; /* Not applicable */
|
wtcb->sigunbinfo->si_pid = 0; /* Not applicable */
|
||||||
wtcb->sigunbinfo->si_status = OK;
|
wtcb->sigunbinfo->si_status = OK;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove the task from waitting list */
|
/* Remove the task from waitting list */
|
||||||
|
|
||||||
@@ -376,6 +382,8 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
rtcb->sigunbinfo = NULL;
|
||||||
|
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user