From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17622 invoked by alias); 10 Feb 2012 14:43:43 -0000 Received: (qmail 17572 invoked by uid 22791); 10 Feb 2012 14:43:41 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE X-Spam-Check-By: sourceware.org Received: from mv-drv-hcb003.ocn.ad.jp (HELO mv-drv-hcb003.ocn.ad.jp) (118.23.109.133) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 10 Feb 2012 14:43:28 +0000 Received: from vcmba.ocn.ne.jp (localhost.localdomain [127.0.0.1]) by mv-drv-hcb003.ocn.ad.jp (Postfix) with ESMTP id 4CB0356421D; Fri, 10 Feb 2012 23:43:27 +0900 (JST) Received: from localhost (softbank221040169135.bbtec.net [221.40.169.135]) by vcmba.ocn.ne.jp (Postfix) with ESMTP; Fri, 10 Feb 2012 23:43:27 +0900 (JST) Date: Fri, 10 Feb 2012 14:43:00 -0000 Message-Id: <20120210.234326.199788933.anemo@mba.ocn.ne.jp> To: libc-alpha@sourceware.org, libc-ports@sourceware.org Subject: pthread_mutex_unlock potentially cause invalid access From: Atsushi Nemoto X-Fingerprint: 6ACA 1623 39BD 9A94 9B1A B746 CA77 FE94 2874 D52F X-Pgp-Public-Key: http://wwwkeys.pgp.net:11371/pks/lookup?op=get&search=0x2874D52F Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Mailing-List: contact libc-ports-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: libc-ports-owner@sourceware.org X-SW-Source: 2012-02/txt/msg00026.txt.bz2 It seems pthread_mutex_unlock() potentially cause invalid access on most platforms (except for i386 and x86_64). # Resend with correct ML address. Excuse me for duplication. In nptl/pthread_mutex_unlock.c, lll_unlock() is called like this: lll_unlock (mutex->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex)); And PTHREAD_MUTEX_PSHARED() is defined like this: # define PTHREAD_MUTEX_PSHARED(m) \ ((m)->__data.__kind & 128) On most platforms, lll_unlock() is defined as a macro like this: #define lll_unlock(lock, private) \ ((void) ({ \ int *__futex = &(lock); \ int __val = atomic_exchange_rel (__futex, 0); \ if (__builtin_expect (__val > 1, 0)) \ lll_futex_wake (__futex, 1, private); \ })) Thus, the lll_unlock() call in pthread_mutex_unlock.c will be expanded as: int *__futex = &(mutex->__data.__lock); int __val = atomic_exchange_rel (__futex, 0); if (__builtin_expect (__val > 1, 0)) /* A */ lll_futex_wake (__futex, 1, ((mutex)->__data.__kind & 128)); /* B */ On point "A", the mutex is actually unlocked, so other threads can lock the mutex, unlock, destroy and free. If the mutex was destroyed and freed by other thread, reading '__kind' on point "B" is not valid. Possible fix would be copying the 'private' argument to an internal local variable before atomic_exchange_rel(). Is it an appropriate fix? --- Atsushi Nemoto