mirror of
https://github.com/apache/nuttx.git
synced 2026-05-13 02:18:38 +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:
@@ -398,7 +398,11 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info)
|
||||
(masked == 0 ||
|
||||
nxsig_ismember(&stcb->sigwaitmask, info->si_signo)))
|
||||
{
|
||||
memcpy(stcb->sigunbinfo, info, sizeof(siginfo_t));
|
||||
if (stcb->sigunbinfo != NULL)
|
||||
{
|
||||
memcpy(stcb->sigunbinfo, info, sizeof(siginfo_t));
|
||||
}
|
||||
|
||||
sigemptyset(&stcb->sigwaitmask);
|
||||
|
||||
if (WDOG_ISACTIVE(&stcb->waitdog))
|
||||
@@ -461,7 +465,11 @@ int nxsig_tcbdispatch(FAR struct tcb_s *stcb, siginfo_t *info)
|
||||
|
||||
if (stcb->task_state == TSTATE_WAIT_SIG)
|
||||
{
|
||||
memcpy(stcb->sigunbinfo, info, sizeof(siginfo_t));
|
||||
if (stcb->sigunbinfo != NULL)
|
||||
{
|
||||
memcpy(stcb->sigunbinfo, info, sizeof(siginfo_t));
|
||||
}
|
||||
|
||||
sigemptyset(&stcb->sigwaitmask);
|
||||
|
||||
if (WDOG_ISACTIVE(&stcb->waitdog))
|
||||
|
||||
@@ -99,14 +99,17 @@ static void nxsig_timeout(wdparm_t arg)
|
||||
{
|
||||
FAR struct tcb_s *rtcb = this_task();
|
||||
|
||||
wtcb->sigunbinfo->si_signo = SIG_WAIT_TIMEOUT;
|
||||
wtcb->sigunbinfo->si_code = SI_TIMER;
|
||||
wtcb->sigunbinfo->si_errno = ETIMEDOUT;
|
||||
wtcb->sigunbinfo->si_value.sival_int = 0;
|
||||
if (wtcb->sigunbinfo != NULL)
|
||||
{
|
||||
wtcb->sigunbinfo->si_signo = SIG_WAIT_TIMEOUT;
|
||||
wtcb->sigunbinfo->si_code = SI_TIMER;
|
||||
wtcb->sigunbinfo->si_errno = ETIMEDOUT;
|
||||
wtcb->sigunbinfo->si_value.sival_int = 0;
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
wtcb->sigunbinfo->si_pid = 0; /* Not applicable */
|
||||
wtcb->sigunbinfo->si_status = OK;
|
||||
wtcb->sigunbinfo->si_pid = 0; /* Not applicable */
|
||||
wtcb->sigunbinfo->si_status = OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Remove the task from waitting list */
|
||||
|
||||
@@ -166,14 +169,17 @@ void nxsig_wait_irq(FAR struct tcb_s *wtcb, int errcode)
|
||||
{
|
||||
FAR struct tcb_s *rtcb = this_task();
|
||||
|
||||
wtcb->sigunbinfo->si_signo = SIG_CANCEL_TIMEOUT;
|
||||
wtcb->sigunbinfo->si_code = SI_USER;
|
||||
wtcb->sigunbinfo->si_errno = errcode;
|
||||
wtcb->sigunbinfo->si_value.sival_int = 0;
|
||||
if (wtcb->sigunbinfo != NULL)
|
||||
{
|
||||
wtcb->sigunbinfo->si_signo = SIG_CANCEL_TIMEOUT;
|
||||
wtcb->sigunbinfo->si_code = SI_USER;
|
||||
wtcb->sigunbinfo->si_errno = errcode;
|
||||
wtcb->sigunbinfo->si_value.sival_int = 0;
|
||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||
wtcb->sigunbinfo->si_pid = 0; /* Not applicable */
|
||||
wtcb->sigunbinfo->si_status = OK;
|
||||
wtcb->sigunbinfo->si_pid = 0; /* Not applicable */
|
||||
wtcb->sigunbinfo->si_status = OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Remove the task from waitting list */
|
||||
|
||||
@@ -376,6 +382,8 @@ int nxsig_timedwait(FAR const sigset_t *set, FAR struct siginfo *info,
|
||||
}
|
||||
else
|
||||
{
|
||||
rtcb->sigunbinfo = NULL;
|
||||
|
||||
leave_critical_section(flags);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user