# HG changeset patch # User Petr Sumbera # Date 1365784623 25200 # Node ID 878f258ea71ebbf9795712decf056100eedb168c # Parent 9aaa91c63cb9241d3a569cf9a3801cd5fe711c83 15992470 xmlInitializeDict() should not pretend that it is thread-safe diff -r 9aaa91c63cb9 -r 878f258ea71e components/libxml2/patches/bug697264.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/libxml2/patches/bug697264.patch Fri Apr 12 09:37:03 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 +Date: Fri, 05 Apr 2013 15:10:41 +0000 +Subject: Remove risk of lockup in dictionary initialization + +Reported by Petr Sumbera +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 +@@ -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); + +@@ -183,7 +198,7 @@ int __xmlRandom(void) { + int ret; + + if (xmlDictInitialized == 0) +- xmlInitializeDict(); ++ __xmlInitializeDict(); + + xmlRMutexLock(xmlDictMutex); + #ifdef HAVE_RAND_R +@@ -522,7 +537,7 @@ xmlDictCreate(void) { + xmlDictPtr dict; + + if (!xmlDictInitialized) +- if (!xmlInitializeDict()) ++ if (!__xmlInitializeDict()) + return(NULL); + + #ifdef DICT_DEBUG_PATTERNS +@@ -590,7 +605,7 @@ xmlDictCreateSub(xmlDictPtr sub) { + int + xmlDictReference(xmlDictPtr dict) { + if (!xmlDictInitialized) +- if (!xmlInitializeDict()) ++ if (!__xmlInitializeDict()) + return(-1); + + if (dict == NULL) return -1; +@@ -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 +@@ -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 +@@ -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) { +@@ -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 +@@ -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