15992470 xmlInitializeDict() should not pretend that it is thread-safe s11-update
authorPetr Sumbera <petr.sumbera@oracle.com>
Thu, 09 May 2013 23:58:19 -0700
branchs11-update
changeset 2620 70885a8bb9bc
parent 2602 5caab247ea3d
child 2621 f16db03950b1
15992470 xmlInitializeDict() should not pretend that it is thread-safe
components/libxml2/patches/bug697264.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/libxml2/patches/bug697264.patch	Thu May 09 23:58:19 2013 -0700
@@ -0,0 +1,131 @@
+https://bugzilla.gnome.org/show_bug.cgi?id=697264
+https://git.gnome.org/browse/libxml2/commit/?id=5fe9e9ed1ccf217e11bd3cb99b1c6bb10cc96ba3
+
+From 5fe9e9ed1ccf217e11bd3cb99b1c6bb10cc96ba3 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <[email protected]>
+Date: Fri, 05 Apr 2013 15:10:41 +0000
+Subject: Remove risk of lockup in dictionary initialization
+
+Reported by Petr Sumbera <[email protected]>
+Two threads entering xmlInitializeDict concurently could lead
+to a lockup due to multiple initializations of the lock used.
+To avoid this problem move this to a new private function
+called from xmlOnceInit() and deprecate the old initalizer.
+Since threaded programs must call xmlInitParser() and this
+will lead to dereference of private data and the call to
+xmlOnceInit() guaranteed to be unique this should be safe now.
+---
+diff --git a/dict.c b/dict.c
+index 164c7f2..5f71d55 100644
+--- a/dict.c
++++ b/dict.c
[email protected]@ -151,13 +151,28 @@ static unsigned int rand_seed = 0;
+  * xmlInitializeDict:
+  *
+  * Do the dictionary mutex initialization.
+- * this function is not thread safe, initialization should
+- * preferably be done once at startup
++ * this function is deprecated
+  *
+  * Returns 0 if initialization was already done, and 1 if that
+  * call led to the initialization
+  */
+ int xmlInitializeDict(void) {
++    return(0);
++}
++
++/**
++ * __xmlInitializeDict:
++ *
++ * This function is not public
++ * Do the dictionary mutex initialization.
++ * this function is not thread safe, initialization should
++ * normally be done once at setup when called from xmlOnceInit()
++ * we may also land in this code if thread support is not compiled in
++ *
++ * Returns 0 if initialization was already done, and 1 if that
++ * call led to the initialization
++ */
++int __xmlInitializeDict(void) {
+     if (xmlDictInitialized)
+         return(1);
+ 
[email protected]@ -183,7 +198,7 @@ int __xmlRandom(void) {
+     int ret;
+ 
+     if (xmlDictInitialized == 0)
+-        xmlInitializeDict();
++        __xmlInitializeDict();
+ 
+     xmlRMutexLock(xmlDictMutex);
+ #ifdef HAVE_RAND_R
[email protected]@ -522,7 +537,7 @@ xmlDictCreate(void) {
+     xmlDictPtr dict;
+ 
+     if (!xmlDictInitialized)
+-        if (!xmlInitializeDict())
++        if (!__xmlInitializeDict())
+             return(NULL);
+ 
+ #ifdef DICT_DEBUG_PATTERNS
[email protected]@ -590,7 +605,7 @@ xmlDictCreateSub(xmlDictPtr sub) {
+ int
+ xmlDictReference(xmlDictPtr dict) {
+     if (!xmlDictInitialized)
+-        if (!xmlInitializeDict())
++        if (!__xmlInitializeDict())
+             return(-1);
+ 
+     if (dict == NULL) return -1;
[email protected]@ -754,7 +769,7 @@ xmlDictFree(xmlDictPtr dict) {
+ 	return;
+ 
+     if (!xmlDictInitialized)
+-        if (!xmlInitializeDict())
++        if (!__xmlInitializeDict())
+             return;
+ 
+     /* decrement the counter, it may be shared by a parser and docs */
+diff --git a/libxml.h b/libxml.h
+index 7558b5f..2da9044 100644
+--- a/libxml.h
++++ b/libxml.h
[email protected]@ -84,6 +84,8 @@ void __xmlGlobalInitMutexLock(void);
+ void __xmlGlobalInitMutexUnlock(void);
+ void __xmlGlobalInitMutexDestroy(void);
+ 
++int __xmlInitializeDict(void);
++
+ #if defined(HAVE_RAND) && defined(HAVE_SRAND) && defined(HAVE_TIME)
+ /*
+  * internal thread safe random function
+diff --git a/threads.c b/threads.c
+index c8414e1..f2f2703 100644
+--- a/threads.c
++++ b/threads.c
[email protected]@ -954,6 +954,7 @@ xmlOnceInit(void)
+ #ifdef HAVE_PTHREAD_H
+     (void) pthread_key_create(&globalkey, xmlFreeGlobalState);
+     mainthread = pthread_self();
++    __xmlInitializeDict();
+ #elif defined(HAVE_WIN32_THREADS)
+     if (!run_once.done) {
+         if (InterlockedIncrement(&run_once.control) == 1) {
[email protected]@ -961,6 +962,7 @@ xmlOnceInit(void)
+             globalkey = TlsAlloc();
+ #endif
+             mainthread = GetCurrentThreadId();
++	    __xmlInitializeDict();
+             run_once.done = 1;
+         } else {
+             /* Another thread is working; give up our slice and
[email protected]@ -974,6 +976,7 @@ xmlOnceInit(void)
+         globalkey = tls_allocate();
+         tls_set(globalkey, NULL);
+         mainthread = find_thread(NULL);
++	__xmlInitializeDict();
+     } else
+         atomic_add(&run_once_init, -1);
+ #endif
+--
+cgit v0.9.1