aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/unix
diff options
context:
space:
mode:
authorNick Alcock <nick.alcock@oracle.com>2016-03-23 13:40:14 +0100
committerFlorian Weimer <fweimer@redhat.com>2016-03-23 13:40:14 +0100
commit7a25d6a84df9fea56963569ceccaaf7c2a88f161 (patch)
treee701185129f1018d96af4555c440e12d0189d33b /sysdeps/unix
parent3c9a4cd16cbc7b79094fec68add2df66061ab5d7 (diff)
downloadglibc-7a25d6a84df9fea56963569ceccaaf7c2a88f161.zip
glibc-7a25d6a84df9fea56963569ceccaaf7c2a88f161.tar.gz
glibc-7a25d6a84df9fea56963569ceccaaf7c2a88f161.tar.bz2
x86, pthread_cond_*wait: Do not depend on %eax not being clobbered
The x86-specific versions of both pthread_cond_wait and pthread_cond_timedwait have (in their fall-back-to-futex-wait slow paths) calls to __pthread_mutex_cond_lock_adjust followed by __pthread_mutex_unlock_usercnt, which load the parameters before the first call but then assume that the first parameter, in %eax, will survive unaffected. This happens to have been true before now, but %eax is a call-clobbered register, and this assumption is not safe: it could change at any time, at GCC's whim, and indeed the stack-protector canary checking code clobbers %eax while checking that the canary is uncorrupted. So reload %eax before calling __pthread_mutex_unlock_usercnt. (Do this unconditionally, even when stack-protection is not in use, because it's the right thing to do, it's a slow path, and anything else is dicing with death.) * sysdeps/unix/sysv/linux/i386/pthread_cond_timedwait.S: Reload call-clobbered %eax on retry path. * sysdeps/unix/sysv/linux/i386/pthread_cond_wait.S: Likewise.
Diffstat (limited to 'sysdeps/unix')
-rw-r--r--sysdeps/unix/sysv/linux/i386/pthread_cond_timedwait.S1
-rw-r--r--sysdeps/unix/sysv/linux/i386/pthread_cond_wait.S1
2 files changed, 2 insertions, 0 deletions
diff --git a/sysdeps/unix/sysv/linux/i386/pthread_cond_timedwait.S b/sysdeps/unix/sysv/linux/i386/pthread_cond_timedwait.S
index 96f8a8d..6256376 100644
--- a/sysdeps/unix/sysv/linux/i386/pthread_cond_timedwait.S
+++ b/sysdeps/unix/sysv/linux/i386/pthread_cond_timedwait.S
@@ -297,6 +297,7 @@ __pthread_cond_timedwait:
correctly. */
movl dep_mutex(%ebx), %eax
call __pthread_mutex_cond_lock_adjust
+ movl dep_mutex(%ebx), %eax
xorl %edx, %edx
call __pthread_mutex_unlock_usercnt
jmp 8b
diff --git a/sysdeps/unix/sysv/linux/i386/pthread_cond_wait.S b/sysdeps/unix/sysv/linux/i386/pthread_cond_wait.S
index 94302b0..5016718 100644
--- a/sysdeps/unix/sysv/linux/i386/pthread_cond_wait.S
+++ b/sysdeps/unix/sysv/linux/i386/pthread_cond_wait.S
@@ -309,6 +309,7 @@ __pthread_cond_wait:
correctly. */
movl dep_mutex(%ebx), %eax
call __pthread_mutex_cond_lock_adjust
+ movl dep_mutex(%ebx), %eax
xorl %edx, %edx
call __pthread_mutex_unlock_usercnt
jmp 8b