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;
             }

Reply via email to