summaryrefslogtreecommitdiff
path: root/source4/torture/smb2
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2017-11-30 12:25:02 -0800
committerJeremy Allison <jra@samba.org>2017-12-01 23:46:14 +0100
commit9f83d435bb21aeb3d309b764170789ed100c9ad7 (patch)
tree144b5ec56caa96edd9892a452fb7ae89c53d8595 /source4/torture/smb2
parentbfd063d7e8f921f8f47d5f43a64f40ef85fcbde9 (diff)
downloadsamba-9f83d435bb21aeb3d309b764170789ed100c9ad7.tar.gz
s4: torture: Fix race condition in test_smb2_kernel_oplocks8.
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>
Diffstat (limited to 'source4/torture/smb2')
-rw-r--r--source4/torture/smb2/oplock.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/source4/torture/smb2/oplock.c b/source4/torture/smb2/oplock.c
index 6d749f92c1c..87d7d2ff946 100644
--- a/source4/torture/smb2/oplock.c
+++ b/source4/torture/smb2/oplock.c
@@ -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;
}