This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new a8de85de0b sched/signal: add sanity check for siginfo
a8de85de0b is described below
commit a8de85de0b18e17ea4d9aa24d790b0949df4e7c7
Author: chao an <[email protected]>
AuthorDate: Tue Mar 26 09:15:32 2024 +0800
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 <[email protected]>
---
sched/signal/sig_dispatch.c | 12 ++++++++++--
sched/signal/sig_timedwait.c | 32 ++++++++++++++++++++------------
2 files changed, 30 insertions(+), 14 deletions(-)
diff --git a/sched/signal/sig_dispatch.c b/sched/signal/sig_dispatch.c
index a657a92a92..45744cb9f5 100644
--- a/sched/signal/sig_dispatch.c
+++ b/sched/signal/sig_dispatch.c
@@ -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))
diff --git a/sched/signal/sig_timedwait.c b/sched/signal/sig_timedwait.c
index 9bbef85438..1b7985deeb 100644
--- a/sched/signal/sig_timedwait.c
+++ b/sched/signal/sig_timedwait.c
@@ -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;
}