]> sourceware.org Git - glibc.git/commitdiff
Fix race in tst-mqueue5
authorPaul E. Murphy <murphyp@linux.vnet.ibm.com>
Mon, 11 Jan 2016 22:24:04 +0000 (17:24 -0500)
committerTulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
Fri, 15 Jan 2016 18:53:08 +0000 (16:53 -0200)
The check is done on line 117 by a thread spawned
from do_child(), forked from do_test().  This test
generates a signal in the forked process.

Either thread may handle the signal, and on ppc,
it happens to be done on do_child, on the thread
which is not doing the check on line 117.

This exposes a race condition whereby the test
incorrectly fails as the signal is caught during
or after the check.

This is mitigated by ensuring the signal is blocked
in the child thread while thread is running.

ChangeLog
rt/tst-mqueue5.c

index 7f2a19d50ab764cf9182932538103b8f438ea796..fb5cd0e024ebed52bae73728a66cb6bcfd106aa4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2016-01-15  Paul E. Murphy  <murphyp@linux.vnet.ibm.com>
+
+       * rt/tst-mqueue5.c (thr): Cleanup misleading comment.
+       (do_child): Mask SIGRTMIN while thr is running.
+
 2016-01-15  Martin Sebor  <msebor@redhat.com>
 
        [BZ #19432]
index aa74fa31ace637989d41811fa4194afebe1f6869..25042bcc9f060e4c887399c67ff835aef7c40f51 100644 (file)
@@ -116,7 +116,7 @@ thr (void *arg)
 
   if (rtmin_cnt != 2)
     {
-      puts ("SIGRTMIN signal in child did not arrive");
+      puts ("SIGRTMIN signal in thread did not arrive");
       result = 1;
     }
   else if (rtmin_pid != getppid ()
@@ -403,6 +403,16 @@ do_child (const char *name, pthread_barrier_t *b2, pthread_barrier_t *b3,
       result = 1;
     }
 
+  /* Ensure the thr thread gets the signal, not us.  */
+  sigset_t set;
+  sigemptyset (&set);
+  sigaddset (&set, SIGRTMIN);
+  if (pthread_sigmask (SIG_BLOCK, &set, NULL))
+    {
+      printf ("Failed to block SIGRTMIN in child: %m\n");
+      result = 1;
+    }
+
   (void) pthread_barrier_wait (b2);
 
   /* Parent calls mqsend (q), which should wake up mqrecv (q)
@@ -514,7 +524,14 @@ do_child (const char *name, pthread_barrier_t *b2, pthread_barrier_t *b3,
       result = 1;
     }
 
- void *thr_ret;
+  /* Reenable test signals before cleaning up the thread.  */
+  if (pthread_sigmask (SIG_UNBLOCK, &set, NULL))
+    {
+      printf ("Failed to unblock SIGRTMIN in child: %m\n");
+      result = 1;
+    }
+
+  void *thr_ret;
   ret = pthread_join (th, &thr_ret);
   if (ret)
     {
This page took 0.196466 seconds and 5 git commands to generate.