Diff for /embedaddon/libxml2/dict.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/21 23:37:58 version 1.1.1.2, 2013/07/22 01:22:19
Line 2 Line 2
  * dict.c: dictionary of reusable strings, just used to avoid allocation   * dict.c: dictionary of reusable strings, just used to avoid allocation
  *         and freeing operations.   *         and freeing operations.
  *   *
 * Copyright (C) 2003 Daniel Veillard. * Copyright (C) 2003-2012 Daniel Veillard.
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above   * purpose with or without fee is hereby granted, provided that the above
Line 19 Line 19
 #define IN_LIBXML  #define IN_LIBXML
 #include "libxml.h"  #include "libxml.h"
   
   #ifdef HAVE_STDLIB_H
   #include <stdlib.h>
   #endif
   #ifdef HAVE_TIME_H
   #include <time.h>
   #endif
   
   /*
    * Following http://www.ocert.org/advisories/ocert-2011-003.html
    * it seems that having hash randomization might be a good idea
    * when using XML with untrusted data
    * Note1: that it works correctly only if compiled with WITH_BIG_KEY
    *  which is the default.
    * Note2: the fast function used for a small dict won't protect very
    *  well but since the attack is based on growing a very big hash
    *  list we will use the BigKey algo as soon as the hash size grows
    *  over MIN_DICT_SIZE so this actually works
    */
   #if defined(HAVE_RAND) && defined(HAVE_SRAND) && defined(HAVE_TIME)
   #define DICT_RANDOMIZATION
   #endif
   
 #include <string.h>  #include <string.h>
 #ifdef HAVE_STDINT_H  #ifdef HAVE_STDINT_H
 #include <stdint.h>  #include <stdint.h>
Line 44  typedef unsigned __int32 uint32_t; Line 66  typedef unsigned __int32 uint32_t;
 #define WITH_BIG_KEY  #define WITH_BIG_KEY
   
 #ifdef WITH_BIG_KEY  #ifdef WITH_BIG_KEY
#define xmlDictComputeKey(dict, name, len)                      \#define xmlDictComputeKey(dict, name, len)                              \
    (((dict)->size == MIN_DICT_SIZE) ?                          \    (((dict)->size == MIN_DICT_SIZE) ?                                  \
     xmlDictComputeFastKey(name, len) :                                \     xmlDictComputeFastKey(name, len, (dict)->seed) :                   \
     xmlDictComputeBigKey(name, len))     xmlDictComputeBigKey(name, len, (dict)->seed))
   
#define xmlDictComputeQKey(dict, prefix, plen, name, len)       \#define xmlDictComputeQKey(dict, prefix, plen, name, len)               \
    (((prefix) == NULL) ?                                       \    (((prefix) == NULL) ?                                               \
      (xmlDictComputeKey(dict, name, len)) :                    \      (xmlDictComputeKey(dict, name, len)) :                             \
      (((dict)->size == MIN_DICT_SIZE) ?                        \      (((dict)->size == MIN_DICT_SIZE) ?                                \
       xmlDictComputeFastQKey(prefix, plen, name, len) :     \       xmlDictComputeFastQKey(prefix, plen, name, len, (dict)->seed) :     \
       xmlDictComputeBigQKey(prefix, plen, name, len)))       xmlDictComputeBigQKey(prefix, plen, name, len, (dict)->seed)))
   
 #else /* !WITH_BIG_KEY */  #else /* !WITH_BIG_KEY */
#define xmlDictComputeKey(dict, name, len)                      \#define xmlDictComputeKey(dict, name, len)                              \
        xmlDictComputeFastKey(name, len)        xmlDictComputeFastKey(name, len, (dict)->seed)
#define xmlDictComputeQKey(dict, prefix, plen, name, len)       \#define xmlDictComputeQKey(dict, prefix, plen, name, len)               \
        xmlDictComputeFastQKey(prefix, plen, name, len)        xmlDictComputeFastQKey(prefix, plen, name, len, (dict)->seed)
 #endif /* WITH_BIG_KEY */  #endif /* WITH_BIG_KEY */
   
 /*  /*
Line 98  struct _xmlDict { Line 120  struct _xmlDict {
     xmlDictStringsPtr strings;      xmlDictStringsPtr strings;
   
     struct _xmlDict *subdict;      struct _xmlDict *subdict;
       /* used for randomization */
       int seed;
 };  };
   
 /*  /*
Line 111  static xmlRMutexPtr xmlDictMutex = NULL; Line 135  static xmlRMutexPtr xmlDictMutex = NULL;
  */   */
 static int xmlDictInitialized = 0;  static int xmlDictInitialized = 0;
   
   #ifdef DICT_RANDOMIZATION
   #ifdef HAVE_RAND_R
   /*
    * Internal data for random function, protected by xmlDictMutex
    */
   unsigned int rand_seed = 0;
   #endif
   #endif
   
 /**  /**
  * xmlInitializeDict:   * xmlInitializeDict:
  *   *
  * Do the dictionary mutex initialization.   * Do the dictionary mutex initialization.
  * this function is not thread safe, initialization should   * this function is not thread safe, initialization should
  * preferably be done once at startup   * preferably be done once at startup
    *
    * Returns 0 if initialization was already done, and 1 if that
    * call led to the initialization
  */   */
static int xmlInitializeDict(void) {int xmlInitializeDict(void) {
     if (xmlDictInitialized)      if (xmlDictInitialized)
         return(1);          return(1);
   
     if ((xmlDictMutex = xmlNewRMutex()) == NULL)      if ((xmlDictMutex = xmlNewRMutex()) == NULL)
         return(0);          return(0);
       xmlRMutexLock(xmlDictMutex);
   
   #ifdef DICT_RANDOMIZATION
   #ifdef HAVE_RAND_R
       rand_seed = time(NULL);
       rand_r(& rand_seed);
   #else
       srand(time(NULL));
   #endif
   #endif
     xmlDictInitialized = 1;      xmlDictInitialized = 1;
       xmlRMutexUnlock(xmlDictMutex);
     return(1);      return(1);
 }  }
   
   #ifdef DICT_RANDOMIZATION
   int __xmlRandom(void) {
       int ret;
   
       if (xmlDictInitialized == 0)
           xmlInitializeDict();
   
       xmlRMutexLock(xmlDictMutex);
   #ifdef HAVE_RAND_R
       ret = rand_r(& rand_seed);
   #else
       ret = rand();
   #endif
       xmlRMutexUnlock(xmlDictMutex);
       return(ret);
   }
   #endif
   
 /**  /**
  * xmlDictCleanup:   * xmlDictCleanup:
  *   *
 * Free the dictionary mutex. * Free the dictionary mutex. Do not call unless sure the library
  * is not in use anymore !
  */   */
 void  void
 xmlDictCleanup(void) {  xmlDictCleanup(void) {
Line 277  found_pool: Line 342  found_pool:
  */   */
   
 static uint32_t  static uint32_t
xmlDictComputeBigKey(const xmlChar* data, int namelen) {xmlDictComputeBigKey(const xmlChar* data, int namelen, int seed) {
     uint32_t hash;      uint32_t hash;
     int i;      int i;
   
     if (namelen <= 0 || data == NULL) return(0);      if (namelen <= 0 || data == NULL) return(0);
   
    hash = 0;    hash = seed;
   
     for (i = 0;i < namelen; i++) {      for (i = 0;i < namelen; i++) {
         hash += data[i];          hash += data[i];
Line 310  xmlDictComputeBigKey(const xmlChar* data, int namelen) Line 375  xmlDictComputeBigKey(const xmlChar* data, int namelen)
  */   */
 static unsigned long  static unsigned long
 xmlDictComputeBigQKey(const xmlChar *prefix, int plen,  xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
                      const xmlChar *name, int len)                      const xmlChar *name, int len, int seed)
 {  {
     uint32_t hash;      uint32_t hash;
     int i;      int i;
   
    hash = 0;    hash = seed;
   
     for (i = 0;i < plen; i++) {      for (i = 0;i < plen; i++) {
         hash += prefix[i];          hash += prefix[i];
Line 346  xmlDictComputeBigQKey(const xmlChar *prefix, int plen, Line 411  xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
  * for low hash table fill.   * for low hash table fill.
  */   */
 static unsigned long  static unsigned long
xmlDictComputeFastKey(const xmlChar *name, int namelen) {xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) {
    unsigned long value = 0L;    unsigned long value = seed;
   
     if (name == NULL) return(0);      if (name == NULL) return(0);
     value = *name;      value = *name;
Line 381  xmlDictComputeFastKey(const xmlChar *name, int namelen Line 446  xmlDictComputeFastKey(const xmlChar *name, int namelen
  */   */
 static unsigned long  static unsigned long
 xmlDictComputeFastQKey(const xmlChar *prefix, int plen,  xmlDictComputeFastQKey(const xmlChar *prefix, int plen,
                       const xmlChar *name, int len)                       const xmlChar *name, int len, int seed)
 {  {
    unsigned long value = 0L;    unsigned long value = (unsigned long) seed;
   
     if (plen == 0)      if (plen == 0)
         value += 30 * (unsigned long) ':';          value += 30 * (unsigned long) ':';
Line 460  xmlDictCreate(void) { Line 525  xmlDictCreate(void) {
         dict->subdict = NULL;          dict->subdict = NULL;
         if (dict->dict) {          if (dict->dict) {
             memset(dict->dict, 0, MIN_DICT_SIZE * sizeof(xmlDictEntry));              memset(dict->dict, 0, MIN_DICT_SIZE * sizeof(xmlDictEntry));
   #ifdef DICT_RANDOMIZATION
               dict->seed = __xmlRandom();
   #else
               dict->seed = 0;
   #endif
             return(dict);              return(dict);
         }          }
         xmlFree(dict);          xmlFree(dict);
Line 486  xmlDictCreateSub(xmlDictPtr sub) { Line 556  xmlDictCreateSub(xmlDictPtr sub) {
 #ifdef DICT_DEBUG_PATTERNS  #ifdef DICT_DEBUG_PATTERNS
         fprintf(stderr, "R");          fprintf(stderr, "R");
 #endif  #endif
           dict->seed = sub->seed;
         dict->subdict = sub;          dict->subdict = sub;
         xmlDictReference(dict->subdict);          xmlDictReference(dict->subdict);
     }      }

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>