components/libxml2/patches/bug697264.patch
changeset 1262 878f258ea71e
equal deleted inserted replaced
1261:9aaa91c63cb9 1262:878f258ea71e
       
     1 https://bugzilla.gnome.org/show_bug.cgi?id=697264
       
     2 https://git.gnome.org/browse/libxml2/commit/?id=5fe9e9ed1ccf217e11bd3cb99b1c6bb10cc96ba3
       
     3 
       
     4 From 5fe9e9ed1ccf217e11bd3cb99b1c6bb10cc96ba3 Mon Sep 17 00:00:00 2001
       
     5 From: Daniel Veillard <[email protected]>
       
     6 Date: Fri, 05 Apr 2013 15:10:41 +0000
       
     7 Subject: Remove risk of lockup in dictionary initialization
       
     8 
       
     9 Reported by Petr Sumbera <[email protected]>
       
    10 Two threads entering xmlInitializeDict concurently could lead
       
    11 to a lockup due to multiple initializations of the lock used.
       
    12 To avoid this problem move this to a new private function
       
    13 called from xmlOnceInit() and deprecate the old initalizer.
       
    14 Since threaded programs must call xmlInitParser() and this
       
    15 will lead to dereference of private data and the call to
       
    16 xmlOnceInit() guaranteed to be unique this should be safe now.
       
    17 ---
       
    18 diff --git a/dict.c b/dict.c
       
    19 index 164c7f2..5f71d55 100644
       
    20 --- a/dict.c
       
    21 +++ b/dict.c
       
    22 @@ -151,13 +151,28 @@ static unsigned int rand_seed = 0;
       
    23   * xmlInitializeDict:
       
    24   *
       
    25   * Do the dictionary mutex initialization.
       
    26 - * this function is not thread safe, initialization should
       
    27 - * preferably be done once at startup
       
    28 + * this function is deprecated
       
    29   *
       
    30   * Returns 0 if initialization was already done, and 1 if that
       
    31   * call led to the initialization
       
    32   */
       
    33  int xmlInitializeDict(void) {
       
    34 +    return(0);
       
    35 +}
       
    36 +
       
    37 +/**
       
    38 + * __xmlInitializeDict:
       
    39 + *
       
    40 + * This function is not public
       
    41 + * Do the dictionary mutex initialization.
       
    42 + * this function is not thread safe, initialization should
       
    43 + * normally be done once at setup when called from xmlOnceInit()
       
    44 + * we may also land in this code if thread support is not compiled in
       
    45 + *
       
    46 + * Returns 0 if initialization was already done, and 1 if that
       
    47 + * call led to the initialization
       
    48 + */
       
    49 +int __xmlInitializeDict(void) {
       
    50      if (xmlDictInitialized)
       
    51          return(1);
       
    52  
       
    53 @@ -183,7 +198,7 @@ int __xmlRandom(void) {
       
    54      int ret;
       
    55  
       
    56      if (xmlDictInitialized == 0)
       
    57 -        xmlInitializeDict();
       
    58 +        __xmlInitializeDict();
       
    59  
       
    60      xmlRMutexLock(xmlDictMutex);
       
    61  #ifdef HAVE_RAND_R
       
    62 @@ -522,7 +537,7 @@ xmlDictCreate(void) {
       
    63      xmlDictPtr dict;
       
    64  
       
    65      if (!xmlDictInitialized)
       
    66 -        if (!xmlInitializeDict())
       
    67 +        if (!__xmlInitializeDict())
       
    68              return(NULL);
       
    69  
       
    70  #ifdef DICT_DEBUG_PATTERNS
       
    71 @@ -590,7 +605,7 @@ xmlDictCreateSub(xmlDictPtr sub) {
       
    72  int
       
    73  xmlDictReference(xmlDictPtr dict) {
       
    74      if (!xmlDictInitialized)
       
    75 -        if (!xmlInitializeDict())
       
    76 +        if (!__xmlInitializeDict())
       
    77              return(-1);
       
    78  
       
    79      if (dict == NULL) return -1;
       
    80 @@ -754,7 +769,7 @@ xmlDictFree(xmlDictPtr dict) {
       
    81  	return;
       
    82  
       
    83      if (!xmlDictInitialized)
       
    84 -        if (!xmlInitializeDict())
       
    85 +        if (!__xmlInitializeDict())
       
    86              return;
       
    87  
       
    88      /* decrement the counter, it may be shared by a parser and docs */
       
    89 diff --git a/libxml.h b/libxml.h
       
    90 index 7558b5f..2da9044 100644
       
    91 --- a/libxml.h
       
    92 +++ b/libxml.h
       
    93 @@ -84,6 +84,8 @@ void __xmlGlobalInitMutexLock(void);
       
    94  void __xmlGlobalInitMutexUnlock(void);
       
    95  void __xmlGlobalInitMutexDestroy(void);
       
    96  
       
    97 +int __xmlInitializeDict(void);
       
    98 +
       
    99  #if defined(HAVE_RAND) && defined(HAVE_SRAND) && defined(HAVE_TIME)
       
   100  /*
       
   101   * internal thread safe random function
       
   102 diff --git a/threads.c b/threads.c
       
   103 index c8414e1..f2f2703 100644
       
   104 --- a/threads.c
       
   105 +++ b/threads.c
       
   106 @@ -954,6 +954,7 @@ xmlOnceInit(void)
       
   107  #ifdef HAVE_PTHREAD_H
       
   108      (void) pthread_key_create(&globalkey, xmlFreeGlobalState);
       
   109      mainthread = pthread_self();
       
   110 +    __xmlInitializeDict();
       
   111  #elif defined(HAVE_WIN32_THREADS)
       
   112      if (!run_once.done) {
       
   113          if (InterlockedIncrement(&run_once.control) == 1) {
       
   114 @@ -961,6 +962,7 @@ xmlOnceInit(void)
       
   115              globalkey = TlsAlloc();
       
   116  #endif
       
   117              mainthread = GetCurrentThreadId();
       
   118 +	    __xmlInitializeDict();
       
   119              run_once.done = 1;
       
   120          } else {
       
   121              /* Another thread is working; give up our slice and
       
   122 @@ -974,6 +976,7 @@ xmlOnceInit(void)
       
   123          globalkey = tls_allocate();
       
   124          tls_set(globalkey, NULL);
       
   125          mainthread = find_thread(NULL);
       
   126 +	__xmlInitializeDict();
       
   127      } else
       
   128          atomic_add(&run_once_init, -1);
       
   129  #endif
       
   130 --
       
   131 cgit v0.9.1