From patchwork Wed Oct 14 19:03:15 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 9136 Received: (qmail 80776 invoked by alias); 14 Oct 2015 19:03:28 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 80758 invoked by uid 89); 14 Oct 2015 19:03:27 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-yk0-f180.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id; bh=kybOuSzlpbSppf0GJbzS/ryJhiBrk6NPr1RdVCFT3pM=; b=BoIzTs+RxpKpA67eLuNQ2/HPNlfr6+Tww2mImglmDJwHaL0SA1qc5aXMkQ5ug4A4HH PIIZ2ZBEFeQcW3cAHv4FLqwBUCRwpRIiwdZAiSjGd1g6OyLMxaZZNsG+pgVPnUG/hzMX +pXrZ9Rb1e03dDhNSYOX00wezVraqAAZO1bICUFCdxEIa2LOC4OZ1q3oW/hcWUnphy+1 PnrzFS8OJAfwxfwWzF5PEm2VirwMY101CGlx60n5n5Qc9k0k7uZeh1sNstFyCP6I3/v+ AgAEOOAi29qzKLHR2pLCD42A3+Yauu0OPGtK0IGAsPbAM5LM2eONxPq4H4ig9IzJlUkG Nmrw== X-Gm-Message-State: ALoCoQnZ6JTIbCIvRzAQsauh9R6QqKZxbSwqRUcxTjFPN9akE71O1hcqZEKGysF9HY0ucNTbitp3 X-Received: by 10.129.51.73 with SMTP id z70mr3525386ywz.148.1444849404373; Wed, 14 Oct 2015 12:03:24 -0700 (PDT) From: Adhemerval Zanella X-Google-Original-From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH] nptl: Fix racy pipe closing in tst-cancel{20,21} Date: Wed, 14 Oct 2015 16:03:15 -0300 Message-Id: <1444849395-18800-1-git-send-email-adhemerval.zanella@linaro.com> The tst-cancel20 open two pipes and creates a thread which blocks reading the first pipe. It then issues a signal to activate an handler which also blocks reading the second pipe. Finally the cancellation cleanup-up handlers are tested by first closing the all the pipe ends and issuing a pthread_cancel. The tst-cancel21 have a similar behavior, but use an extra fork after the test itself. The race condition occurs if the cancellation handling acts after the pipe close: in this case read will return EOF (indicating side-effects) and thus the cancellation must not act. However current GLIBC cancellation behavior acts regardless the syscalls returns with sid-effects. This patch adjust the test by moving the pipe closing after the cancellation handling. This avoid spurious cancellation for the case described. Checked on x86_64 and i386. * nptl/tst-cancel20.c (do_one_test): Move the pipe closing after pthread_join. * nptl/tst-cancel21.c (tf): Likewise. --- ChangeLog | 6 ++++++ nptl/tst-cancel20.c | 15 +++++++++------ nptl/tst-cancel21.c | 15 +++++++++------ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/nptl/tst-cancel20.c b/nptl/tst-cancel20.c index 51b558e..91452fb 100644 --- a/nptl/tst-cancel20.c +++ b/nptl/tst-cancel20.c @@ -145,12 +145,6 @@ do_one_test (void) return 1; } - /* This will cause the read in the child to return. */ - close (fd[0]); - close (fd[1]); - close (fd[2]); - close (fd[3]); - void *ret; if (pthread_join (th, &ret) != 0) { @@ -170,6 +164,15 @@ do_one_test (void) return 1; } + /* The pipe closing must be issued after the cancellation handling to avoid + a race condition where the cancellation runs after both pipe ends are + closed. In this case the read syscall returns EOF and the cancellation + must not act. */ + close (fd[0]); + close (fd[1]); + close (fd[2]); + close (fd[3]); + return 0; } diff --git a/nptl/tst-cancel21.c b/nptl/tst-cancel21.c index b54f236..d082776 100644 --- a/nptl/tst-cancel21.c +++ b/nptl/tst-cancel21.c @@ -123,12 +123,6 @@ tf (void *arg) exit (1); } - /* This will cause the read in the initial thread to return. */ - close (fd[0]); - close (fd[1]); - close (fd[2]); - close (fd[3]); - void *ret; if (pthread_join (th, &ret) != 0) { @@ -154,6 +148,15 @@ tf (void *arg) exit (1); } + /* The pipe closing must be issued after the cancellation handling to avoid + a race condition where the cancellation runs after both pipe ends are + closed. In this case the read syscall returns EOF and the cancellation + must not act. */ + close (fd[0]); + close (fd[1]); + close (fd[2]); + close (fd[3]); + exit (0); }