mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-03-23 02:50:08 +03:00
dict: Use xoroshiro64** as PRNG
Stop using rand_r. This enables hash randomization on all platforms.
This commit is contained in:
parent
6d7aaaa835
commit
57cfd221a6
@ -157,7 +157,6 @@ if (NOT MSVC)
|
||||
check_include_files(netdb.h HAVE_NETDB_H)
|
||||
check_include_files(netinet/in.h HAVE_NETINET_IN_H)
|
||||
check_include_files(poll.h HAVE_POLL_H)
|
||||
check_function_exists(rand_r HAVE_RAND_R)
|
||||
check_library_exists(dld shl_load "" HAVE_SHLLOAD)
|
||||
check_function_exists(stat HAVE_STAT)
|
||||
check_include_files(stdint.h HAVE_STDINT_H)
|
||||
|
@ -60,9 +60,6 @@
|
||||
/* Define if <pthread.h> is there */
|
||||
#cmakedefine HAVE_PTHREAD_H 1
|
||||
|
||||
/* Define to 1 if you have the `rand_r' function. */
|
||||
#cmakedefine HAVE_RAND_R 1
|
||||
|
||||
/* Have shl_load based dso */
|
||||
#cmakedefine HAVE_SHLLOAD 1
|
||||
|
||||
|
@ -307,7 +307,7 @@ dnl
|
||||
AC_CHECK_FUNCS(snprintf vsnprintf,, NEED_TRIO=1)
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_CHECK_FUNCS([gettimeofday ftime stat rand_r isascii mmap munmap])
|
||||
AC_CHECK_FUNCS([gettimeofday ftime stat isascii mmap munmap])
|
||||
|
||||
AH_VERBATIM([HAVE_MUNMAP_AFTER],[/* mmap() is no good without munmap() */
|
||||
#if defined(HAVE_MMAP) && !defined(HAVE_MUNMAP)
|
||||
|
111
dict.c
111
dict.c
@ -20,12 +20,24 @@
|
||||
#include "libxml.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "private/dict.h"
|
||||
#include "private/threads.h"
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#elif defined(_WIN32)
|
||||
typedef unsigned __int32 uint32_t;
|
||||
#endif
|
||||
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/dict.h>
|
||||
#include <libxml/xmlmemory.h>
|
||||
#include <libxml/xmlerror.h>
|
||||
#include <libxml/globals.h>
|
||||
|
||||
/*
|
||||
* Following http://www.ocert.org/advisories/ocert-2011-003.html
|
||||
* it seems that having hash randomization might be a good idea
|
||||
@ -41,22 +53,6 @@
|
||||
#define DICT_RANDOMIZATION
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#elif defined(_WIN32)
|
||||
typedef unsigned __int32 uint32_t;
|
||||
#endif
|
||||
#endif
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/dict.h>
|
||||
#include <libxml/xmlmemory.h>
|
||||
#include <libxml/xmlerror.h>
|
||||
#include <libxml/globals.h>
|
||||
|
||||
/* #define DEBUG_GROW */
|
||||
/* #define DICT_DEBUG_PATTERNS */
|
||||
|
||||
@ -122,7 +118,7 @@ struct _xmlDict {
|
||||
|
||||
struct _xmlDict *subdict;
|
||||
/* used for randomization */
|
||||
int seed;
|
||||
unsigned seed;
|
||||
/* used to impose a limit on size */
|
||||
size_t limit;
|
||||
};
|
||||
@ -133,59 +129,72 @@ struct _xmlDict {
|
||||
*/
|
||||
static xmlMutex xmlDictMutex;
|
||||
|
||||
#ifdef DICT_RANDOMIZATION
|
||||
#ifdef HAVE_RAND_R
|
||||
/*
|
||||
* Internal data for random function, protected by xmlDictMutex
|
||||
*/
|
||||
static unsigned int rand_seed = 0;
|
||||
#endif
|
||||
#endif
|
||||
static uint32_t rand_seed[2];
|
||||
|
||||
/**
|
||||
* xmlInitializeDict:
|
||||
*
|
||||
* DEPRECATED: Alias for xmlInitParser.
|
||||
*/
|
||||
int xmlInitializeDict(void) {
|
||||
int
|
||||
xmlInitializeDict(void) {
|
||||
xmlInitParser();
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* __xmlInitializeDict:
|
||||
* xmlInitializeDict:
|
||||
*
|
||||
* This function is not public
|
||||
* Do the dictionary mutex initialization.
|
||||
* Initialize mutex and global PRNG seed.
|
||||
*/
|
||||
int __xmlInitializeDict(void) {
|
||||
#ifdef __clang__
|
||||
ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
|
||||
ATTRIBUTE_NO_SANITIZE("unsigned-shift-base")
|
||||
#endif
|
||||
void
|
||||
xmlInitDictInternal(void) {
|
||||
int var;
|
||||
|
||||
xmlInitMutex(&xmlDictMutex);
|
||||
|
||||
#ifdef DICT_RANDOMIZATION
|
||||
#ifdef HAVE_RAND_R
|
||||
rand_seed = time(NULL);
|
||||
rand_r(& rand_seed);
|
||||
#else
|
||||
srand(time(NULL));
|
||||
#endif
|
||||
#endif
|
||||
return(1);
|
||||
/* TODO: Get seed values from system PRNG */
|
||||
|
||||
rand_seed[0] = (uint32_t) time(NULL) ^
|
||||
HASH_ROL((uint32_t) (size_t) &xmlInitializeDict, 8);
|
||||
rand_seed[1] = HASH_ROL((uint32_t) (size_t) &xmlDictMutex, 16) ^
|
||||
HASH_ROL((uint32_t) (size_t) &var, 24);
|
||||
}
|
||||
|
||||
#ifdef DICT_RANDOMIZATION
|
||||
int __xmlRandom(void) {
|
||||
int ret;
|
||||
#ifdef __clang__
|
||||
ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
|
||||
ATTRIBUTE_NO_SANITIZE("unsigned-shift-base")
|
||||
#endif
|
||||
static uint32_t
|
||||
xoroshiro64ss(uint32_t *s) {
|
||||
uint32_t s0 = s[0];
|
||||
uint32_t s1 = s[1];
|
||||
uint32_t result = HASH_ROL(s0 * 0x9E3779BB, 5) * 5;
|
||||
|
||||
s1 ^= s0;
|
||||
s[0] = HASH_ROL(s0, 26) ^ s1 ^ (s1 << 9);
|
||||
s[1] = HASH_ROL(s1, 13);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned
|
||||
xmlRandom(void) {
|
||||
uint32_t ret;
|
||||
|
||||
xmlMutexLock(&xmlDictMutex);
|
||||
#ifdef HAVE_RAND_R
|
||||
ret = rand_r(& rand_seed);
|
||||
#else
|
||||
ret = rand();
|
||||
#endif
|
||||
ret = xoroshiro64ss(rand_seed);
|
||||
xmlMutexUnlock(&xmlDictMutex);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* xmlDictCleanup:
|
||||
@ -358,7 +367,7 @@ ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
|
||||
ATTRIBUTE_NO_SANITIZE("unsigned-shift-base")
|
||||
#endif
|
||||
static uint32_t
|
||||
xmlDictComputeBigKey(const xmlChar* data, int namelen, int seed) {
|
||||
xmlDictComputeBigKey(const xmlChar* data, int namelen, unsigned seed) {
|
||||
uint32_t hash;
|
||||
int i;
|
||||
|
||||
@ -395,7 +404,7 @@ ATTRIBUTE_NO_SANITIZE("unsigned-shift-base")
|
||||
#endif
|
||||
static unsigned long
|
||||
xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
|
||||
const xmlChar *name, int len, int seed)
|
||||
const xmlChar *name, int len, unsigned seed)
|
||||
{
|
||||
uint32_t hash;
|
||||
int i;
|
||||
@ -431,7 +440,7 @@ xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
|
||||
* for low hash table fill.
|
||||
*/
|
||||
static unsigned long
|
||||
xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) {
|
||||
xmlDictComputeFastKey(const xmlChar *name, int namelen, unsigned seed) {
|
||||
unsigned long value = seed;
|
||||
|
||||
if ((name == NULL) || (namelen <= 0))
|
||||
@ -476,7 +485,7 @@ xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) {
|
||||
*/
|
||||
static unsigned long
|
||||
xmlDictComputeFastQKey(const xmlChar *prefix, int plen,
|
||||
const xmlChar *name, int len, int seed)
|
||||
const xmlChar *name, int len, unsigned seed)
|
||||
{
|
||||
unsigned long value = seed;
|
||||
|
||||
@ -578,7 +587,7 @@ xmlDictCreate(void) {
|
||||
if (dict->dict) {
|
||||
memset(dict->dict, 0, MIN_DICT_SIZE * sizeof(xmlDictEntry));
|
||||
#ifdef DICT_RANDOMIZATION
|
||||
dict->seed = __xmlRandom();
|
||||
dict->seed = xmlRandom();
|
||||
#else
|
||||
dict->seed = 0;
|
||||
#endif
|
||||
|
14
hash.c
14
hash.c
@ -70,9 +70,7 @@ struct _xmlHashTable {
|
||||
int size;
|
||||
int nbElems;
|
||||
xmlDictPtr dict;
|
||||
#ifdef HASH_RANDOMIZATION
|
||||
int random_seed;
|
||||
#endif
|
||||
unsigned random_seed;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -86,12 +84,10 @@ ATTRIBUTE_NO_SANITIZE("unsigned-shift-base")
|
||||
static unsigned long
|
||||
xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *name,
|
||||
const xmlChar *name2, const xmlChar *name3) {
|
||||
unsigned long value = 0L;
|
||||
unsigned long value;
|
||||
unsigned long ch;
|
||||
|
||||
#ifdef HASH_RANDOMIZATION
|
||||
value = table->random_seed;
|
||||
#endif
|
||||
if (name != NULL) {
|
||||
value += 30 * (*name);
|
||||
while ((ch = *name++) != 0) {
|
||||
@ -122,12 +118,10 @@ xmlHashComputeQKey(xmlHashTablePtr table,
|
||||
const xmlChar *prefix, const xmlChar *name,
|
||||
const xmlChar *prefix2, const xmlChar *name2,
|
||||
const xmlChar *prefix3, const xmlChar *name3) {
|
||||
unsigned long value = 0L;
|
||||
unsigned long value;
|
||||
unsigned long ch;
|
||||
|
||||
#ifdef HASH_RANDOMIZATION
|
||||
value = table->random_seed;
|
||||
#endif
|
||||
if (prefix != NULL)
|
||||
value += 30 * (*prefix);
|
||||
else
|
||||
@ -197,7 +191,7 @@ xmlHashCreate(int size) {
|
||||
if (table->table) {
|
||||
memset(table->table, 0, size * sizeof(xmlHashEntry));
|
||||
#ifdef HASH_RANDOMIZATION
|
||||
table->random_seed = __xmlRandom();
|
||||
table->random_seed = xmlRandom();
|
||||
#endif
|
||||
return(table);
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
#ifndef XML_DICT_H_PRIVATE__
|
||||
#define XML_DICT_H_PRIVATE__
|
||||
|
||||
XML_HIDDEN int
|
||||
__xmlInitializeDict(void);
|
||||
#define HASH_ROL(x,n) ((x) << (n) | ((x) & 0xFFFFFFFF) >> (32 - (n)))
|
||||
|
||||
XML_HIDDEN void
|
||||
xmlInitDictInternal(void);
|
||||
XML_HIDDEN void
|
||||
xmlCleanupDictInternal(void);
|
||||
XML_HIDDEN int
|
||||
__xmlRandom(void);
|
||||
XML_HIDDEN unsigned
|
||||
xmlRandom(void);
|
||||
|
||||
#endif /* XML_DICT_H_PRIVATE__ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user