bca718
commit a3e5b4feeb54cb92657ec2bc6d9be1fcef9e8575
bca718
Author: Paul E. Murphy <murphyp@linux.vnet.ibm.com>
bca718
Date:   Mon Jan 11 17:24:04 2016 -0500
bca718
bca718
    Fix race in tst-mqueue5
bca718
    
bca718
    The check is done on line 117 by a thread spawned
bca718
    from do_child(), forked from do_test().  This test
bca718
    generates a signal in the forked process.
bca718
    
bca718
    Either thread may handle the signal, and on ppc,
bca718
    it happens to be done on do_child, on the thread
bca718
    which is not doing the check on line 117.
bca718
    
bca718
    This exposes a race condition whereby the test
bca718
    incorrectly fails as the signal is caught during
bca718
    or after the check.
bca718
    
bca718
    This is mitigated by ensuring the signal is blocked
bca718
    in the child thread while thread is running.
bca718
bca718
 2016-01-15  Martin Sebor  <msebor@redhat.com>
bca718
 
bca718
 	[BZ #19432]
bca718
diff --git a/rt/tst-mqueue5.c b/rt/tst-mqueue5.c
bca718
index aa74fa3..25042bc 100644
bca718
--- a/rt/tst-mqueue5.c
bca718
+++ b/rt/tst-mqueue5.c
bca718
@@ -116,7 +116,7 @@ thr (void *arg)
bca718
 
bca718
   if (rtmin_cnt != 2)
bca718
     {
bca718
-      puts ("SIGRTMIN signal in child did not arrive");
bca718
+      puts ("SIGRTMIN signal in thread did not arrive");
bca718
       result = 1;
bca718
     }
bca718
   else if (rtmin_pid != getppid ()
bca718
@@ -403,6 +403,16 @@ do_child (const char *name, pthread_barrier_t *b2, pthread_barrier_t *b3,
bca718
       result = 1;
bca718
     }
bca718
 
bca718
+  /* Ensure the thr thread gets the signal, not us.  */
bca718
+  sigset_t set;
bca718
+  sigemptyset (&set);
bca718
+  sigaddset (&set, SIGRTMIN);
bca718
+  if (pthread_sigmask (SIG_BLOCK, &set, NULL))
bca718
+    {
bca718
+      printf ("Failed to block SIGRTMIN in child: %m\n");
bca718
+      result = 1;
bca718
+    }
bca718
+
bca718
   (void) pthread_barrier_wait (b2);
bca718
 
bca718
   /* Parent calls mqsend (q), which should wake up mqrecv (q)
bca718
@@ -514,7 +524,14 @@ do_child (const char *name, pthread_barrier_t *b2, pthread_barrier_t *b3,
bca718
       result = 1;
bca718
     }
bca718
 
bca718
- void *thr_ret;
bca718
+  /* Reenable test signals before cleaning up the thread.  */
bca718
+  if (pthread_sigmask (SIG_UNBLOCK, &set, NULL))
bca718
+    {
bca718
+      printf ("Failed to unblock SIGRTMIN in child: %m\n");
bca718
+      result = 1;
bca718
+    }
bca718
+
bca718
+  void *thr_ret;
bca718
   ret = pthread_join (th, &thr_ret);
bca718
   if (ret)
bca718
     {