1
0
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:
Nick Wellnhofer 2023-09-01 14:52:04 +02:00
parent 6d7aaaa835
commit 57cfd221a6
7 changed files with 72 additions and 71 deletions

View File

@ -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)

View File

@ -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

View File

@ -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
View File

@ -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
View File

@ -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);
}

View File

@ -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__ */

View File

@ -13702,7 +13702,7 @@ xmlInitParser(void) {
xmlInitThreadsInternal();
xmlInitGlobalsInternal();
xmlInitMemoryInternal();
__xmlInitializeDict();
xmlInitDictInternal();
xmlInitEncodingInternal();
xmlRegisterDefaultInputCallbacks();
#ifdef LIBXML_OUTPUT_ENABLED