[libvirt] [PATCH] win32: Properly handle TlsGetValue returning NULL

virThreadSelf tries to access the virThreadPtr stored in TLS for the current thread via TlsGetValue. When virThreadSelf is called on a thread that was not created via virThreadCreate (e.g. the main thread) then TlsGetValue returns NULL as TlsAlloc initializes TLS slots to NULL. virThreadSelf can be called on the main thread via this call chain from virsh vshDeinit virEventAddTimeout virEventPollAddTimeout virEventPollInterruptLocked virThreadIsSelf triggering a segfault as virThreadSelf unconditionally dereferences the return value of TlsGetValue. Fix this by making virThreadSelf check the TLS slot value for NULL and setting the given virThreadPtr accordingly. Reported by Marcel Müller. --- src/util/threads-win32.c | 11 +++++++++-- 1 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/util/threads-win32.c b/src/util/threads-win32.c index 157439c..20756a1 100644 --- a/src/util/threads-win32.c +++ b/src/util/threads-win32.c @@ -316,8 +316,15 @@ int virThreadCreate(virThreadPtr thread, void virThreadSelf(virThreadPtr thread) { virThreadPtr self = TlsGetValue(selfkey); - thread->thread = self->thread; - thread->joinable = self->joinable; + + if (self == NULL) { + /* called on a thread not created by virThreadCreate, e.g. the main thread */ + thread->thread = 0; + thread->joinable = false; + } else { + thread->thread = self->thread; + thread->joinable = self->joinable; + } } bool virThreadIsSelf(virThreadPtr thread) -- 1.7.4.1

On 04/21/2012 11:11 AM, Matthias Bolte wrote:
virThreadSelf tries to access the virThreadPtr stored in TLS for the current thread via TlsGetValue. When virThreadSelf is called on a thread that was not created via virThreadCreate (e.g. the main thread) then TlsGetValue returns NULL as TlsAlloc initializes TLS slots to NULL.
virThreadSelf can be called on the main thread via this call chain from virsh
vshDeinit virEventAddTimeout virEventPollAddTimeout virEventPollInterruptLocked virThreadIsSelf
triggering a segfault as virThreadSelf unconditionally dereferences the return value of TlsGetValue.
Fix this by making virThreadSelf check the TLS slot value for NULL and setting the given virThreadPtr accordingly.
Reported by Marcel Müller. --- src/util/threads-win32.c | 11 +++++++++-- 1 files changed, 9 insertions(+), 2 deletions(-)
ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Am 22. April 2012 04:32 schrieb Eric Blake <eblake@redhat.com>:
On 04/21/2012 11:11 AM, Matthias Bolte wrote:
virThreadSelf tries to access the virThreadPtr stored in TLS for the current thread via TlsGetValue. When virThreadSelf is called on a thread that was not created via virThreadCreate (e.g. the main thread) then TlsGetValue returns NULL as TlsAlloc initializes TLS slots to NULL.
virThreadSelf can be called on the main thread via this call chain from virsh
vshDeinit virEventAddTimeout virEventPollAddTimeout virEventPollInterruptLocked virThreadIsSelf
triggering a segfault as virThreadSelf unconditionally dereferences the return value of TlsGetValue.
Fix this by making virThreadSelf check the TLS slot value for NULL and setting the given virThreadPtr accordingly.
Reported by Marcel Müller. --- src/util/threads-win32.c | 11 +++++++++-- 1 files changed, 9 insertions(+), 2 deletions(-)
ACK.
Thanks, pushed. -- Matthias Bolte http://photron.blogspot.com
participants (2)
-
Eric Blake
-
Matthias Bolte