From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/13288 Path: news.gmane.org!.POSTED!not-for-mail From: Kaarle Ritvanen Newsgroups: gmane.linux.lib.musl.general Subject: [PATCH v2] fix race condition in file locking Date: Tue, 18 Sep 2018 10:03:27 +0300 Message-ID: <20180918070327.32154-1-kaarle.ritvanen@datakunkku.fi> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org X-Trace: blaine.gmane.org 1537254108 9971 195.159.176.226 (18 Sep 2018 07:01:48 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Tue, 18 Sep 2018 07:01:48 +0000 (UTC) Cc: Kaarle Ritvanen To: musl@lists.openwall.com Original-X-From: musl-return-13304-gllmg-musl=m.gmane.org@lists.openwall.com Tue Sep 18 09:01:44 2018 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1g2A12-0002Uh-Bl for gllmg-musl@m.gmane.org; Tue, 18 Sep 2018 09:01:44 +0200 Original-Received: (qmail 3116 invoked by uid 550); 18 Sep 2018 07:03:52 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 3084 invoked from network); 18 Sep 2018 07:03:52 -0000 X-Virus-Scanned: Debian amavisd-new at pp.htv.fi X-Authentication-Warning: kanala.kunkku.net: kaarle set sender to kaarle.ritvanen@datakunkku.fi using -f X-Mailer: git-send-email 2.14.4 Xref: news.gmane.org gmane.linux.lib.musl.general:13288 Archived-At: The condition occurs when - thread #1 is holding the lock - thread #2 is waiting for it on __futexwait - thread #1 is about to release the lock and performs a_swap - thread #3 enters the __lockfile function and manages to grab the lock before thread #1 calls __wake, resetting the MAYBE_WAITERS flag - thread #1 calls __wake - thread #2 wakes up but goes again to __futexwait as the lock is held by thread #3 - thread #3 releases the lock but does not call __wake as the MAYBE_WAITERS flag is not set This condition results in thread #2 not being woken up. This patch fixes the problem by making the woken up thread ensure that the flag is properly set before going to sleep again. --- src/stdio/__lockfile.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/stdio/__lockfile.c b/src/stdio/__lockfile.c index 2ff75d8a..0dcb2a42 100644 --- a/src/stdio/__lockfile.c +++ b/src/stdio/__lockfile.c @@ -8,13 +8,13 @@ int __lockfile(FILE *f) int owner = f->lock, tid = __pthread_self()->tid; if ((owner & ~MAYBE_WAITERS) == tid) return 0; - for (;;) { - owner = a_cas(&f->lock, 0, tid); - if (!owner) return 1; - if (a_cas(&f->lock, owner, owner|MAYBE_WAITERS)==owner) break; + owner = a_cas(&f->lock, 0, tid); + if (!owner) return 1; + while ((owner = a_cas(&f->lock, 0, tid|MAYBE_WAITERS))) { + if ((owner & MAYBE_WAITERS) || + a_cas(&f->lock, owner, owner|MAYBE_WAITERS)==owner) + __futexwait(&f->lock, owner|MAYBE_WAITERS, 1); } - while ((owner = a_cas(&f->lock, 0, tid|MAYBE_WAITERS))) - __futexwait(&f->lock, owner, 1); return 1; } -- 2.14.4