s4: torture: Fix race condition in test_smb2_kernel_oplocks8.
authorJeremy Allison <jra@samba.org>
Thu, 30 Nov 2017 20:25:02 +0000 (12:25 -0800)
committerJeremy Allison <jra@samba.org>
Fri, 1 Dec 2017 22:46:14 +0000 (23:46 +0100)
The child process gets the kernel lease and then notifies
the parent process to continue by writing a byte up a pipe.
It then sets the alarm and calls pause() to wait for the
parent process to contact the smbd and get it to trigger
the break request using an open call.

It is possible for the parent to run and trigger the break
request after the child has written to the pipe, but *before*
the child calls pause(). We then miss the signal notifying
the child to break the lease.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13121

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Böhme <slow@samba.org>
source4/torture/smb2/oplock.c

index 6d749f92c1c1ec4a5c88a7683f9b3380035f5495..87d7d2ff9463507582588b3c0f7383b6d0a12c9a 100644 (file)
@@ -4838,6 +4838,18 @@ static int do_child_process(int pipefd, const char *name)
        int fd = -1;
        char c = 0;
        struct sigaction act;
+       sigset_t set;
+       sigset_t empty_set;
+
+       /* Block RT_SIGNAL_LEASE and SIGALRM. */
+       sigemptyset(&set);
+       sigemptyset(&empty_set);
+       sigaddset(&set, RT_SIGNAL_LEASE);
+       sigaddset(&set, SIGALRM);
+       ret = sigprocmask(SIG_SETMASK, &set, NULL);
+       if (ret == -1) {
+               return 11;
+       }
 
        /* Set up a signal handler for RT_SIGNAL_LEASE. */
        ZERO_STRUCT(act);
@@ -4878,8 +4890,8 @@ static int do_child_process(int pipefd, const char *name)
        /* Ensure the pause doesn't hang forever. */
        alarm(5);
 
-       /* Wait for RT_SIGNAL_LEASE. */
-       ret = pause();
+       /* Wait for RT_SIGNAL_LEASE or SIGALRM. */
+       ret = sigsuspend(&empty_set);
        if (ret != -1 || errno != EINTR) {
                return 6;
        }