]> git.saurik.com Git - redis.git/commitdiff
Fix for hash table collision attack. We simply randomize hash table initialization...
authorantirez <antirez@gmail.com>
Sat, 21 Jan 2012 22:05:32 +0000 (23:05 +0100)
committerantirez <antirez@gmail.com>
Sat, 21 Jan 2012 22:30:13 +0000 (23:30 +0100)
src/debug.c
src/dict.c
src/dict.h
src/redis.c

index f16bcfd16a9094012d9ce5694f7d5f7988d234a3..54920032fd891262edec0fdacb8f0ac381366b7f 100644 (file)
@@ -589,6 +589,8 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
     /* Log INFO and CLIENT LIST */
     redisLog(REDIS_WARNING, "--- INFO OUTPUT");
     infostring = genRedisInfoString("all");
+    infostring = sdscatprintf(infostring, "hash_init_value: %u\n",
+        dictGetHashFunctionSeed());
     redisLogRaw(REDIS_WARNING, infostring);
     redisLog(REDIS_WARNING, "--- CLIENT LIST OUTPUT");
     clients = getAllClientsInfoString();
index a573bcd6e3575477f1e58c67811b46122972de88..a329137544eb86738c055f640c6ad046e34d76e2 100644 (file)
@@ -85,10 +85,20 @@ unsigned int dictIdentityHashFunction(unsigned int key)
     return key;
 }
 
+static int dict_hash_function_seed = 5183;
+
+void dictSetHashFunctionSeed(unsigned int seed) {
+    dict_hash_function_seed = seed;
+}
+
+unsigned int dictGetHashFunctionSeed(void) {
+    return dict_hash_function_seed;
+}
+
 /* Generic hash function (a popular one from Bernstein).
  * I tested a few and this was the best. */
 unsigned int dictGenHashFunction(const unsigned char *buf, int len) {
-    unsigned int hash = 5381;
+    unsigned int hash = dict_hash_function_seed;
 
     while (len--)
         hash = ((hash << 5) + hash) + (*buf++); /* hash * 33 + c */
@@ -97,7 +107,7 @@ unsigned int dictGenHashFunction(const unsigned char *buf, int len) {
 
 /* And a case insensitive version */
 unsigned int dictGenCaseHashFunction(const unsigned char *buf, int len) {
-    unsigned int hash = 5381;
+    unsigned int hash = dict_hash_function_seed;
 
     while (len--)
         hash = ((hash << 5) + hash) + (tolower(*buf++)); /* hash * 33 + c */
index 76451047324bd0de58c92d31c056899e1ec4dd55..5f85695354471b29ab074f974368a673a5bfc45b 100644 (file)
@@ -162,6 +162,8 @@ void dictEnableResize(void);
 void dictDisableResize(void);
 int dictRehash(dict *d, int n);
 int dictRehashMilliseconds(dict *d, int ms);
+void dictSetHashFunctionSeed(unsigned int initval);
+unsigned int dictGetHashFunctionSeed(void);
 
 /* Hash table types */
 extern dictType dictTypeHeapStringCopyKey;
index 3914003d04b3b0c5987a82c9e8e2f155101bbbd9..7446e72e41113cf76571615f58e35b0715c16da4 100644 (file)
@@ -1080,8 +1080,6 @@ void initServer() {
     scriptingInit();
     slowlogInit();
     bioInit();
-    srand(time(NULL)^getpid());
-
 }
 
 /* Populates the Redis Command Table starting from the hard coded list
@@ -1959,9 +1957,15 @@ void setupSignalHandlers(void) {
 
 int main(int argc, char **argv) {
     long long start;
+    struct timeval tv;
 
+    /* We need to initialize our libraries, and the server. */
     zmalloc_enable_thread_safeness();
+    srand(time(NULL)^getpid());
+    gettimeofday(&tv,NULL);
+    dictSetHashFunctionSeed(tv.tv_sec^tv.tv_usec^getpid());
     initServerConfig();
+
     if (argc >= 2) {
         int j = 1; /* First option to parse in argv[] */
         sds options = sdsempty();