mirror of https://github.com/redis/redis.git
				
				
				
			Fix for hash table collision attack. We simply randomize hash table initialization value at startup time.
This commit is contained in:
		
							parent
							
								
									447ebf3bc7
								
							
						
					
					
						commit
						a48c8d873b
					
				| 
						 | 
					@ -589,6 +589,8 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
 | 
				
			||||||
    /* Log INFO and CLIENT LIST */
 | 
					    /* Log INFO and CLIENT LIST */
 | 
				
			||||||
    redisLog(REDIS_WARNING, "--- INFO OUTPUT");
 | 
					    redisLog(REDIS_WARNING, "--- INFO OUTPUT");
 | 
				
			||||||
    infostring = genRedisInfoString("all");
 | 
					    infostring = genRedisInfoString("all");
 | 
				
			||||||
 | 
					    infostring = sdscatprintf(infostring, "hash_init_value: %u\n",
 | 
				
			||||||
 | 
					        dictGetHashFunctionSeed());
 | 
				
			||||||
    redisLogRaw(REDIS_WARNING, infostring);
 | 
					    redisLogRaw(REDIS_WARNING, infostring);
 | 
				
			||||||
    redisLog(REDIS_WARNING, "--- CLIENT LIST OUTPUT");
 | 
					    redisLog(REDIS_WARNING, "--- CLIENT LIST OUTPUT");
 | 
				
			||||||
    clients = getAllClientsInfoString();
 | 
					    clients = getAllClientsInfoString();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/dict.c
								
								
								
								
							
							
						
						
									
										14
									
								
								src/dict.c
								
								
								
								
							| 
						 | 
					@ -85,10 +85,20 @@ unsigned int dictIdentityHashFunction(unsigned int key)
 | 
				
			||||||
    return 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).
 | 
					/* Generic hash function (a popular one from Bernstein).
 | 
				
			||||||
 * I tested a few and this was the best. */
 | 
					 * I tested a few and this was the best. */
 | 
				
			||||||
unsigned int dictGenHashFunction(const unsigned char *buf, int len) {
 | 
					unsigned int dictGenHashFunction(const unsigned char *buf, int len) {
 | 
				
			||||||
    unsigned int hash = 5381;
 | 
					    unsigned int hash = dict_hash_function_seed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (len--)
 | 
					    while (len--)
 | 
				
			||||||
        hash = ((hash << 5) + hash) + (*buf++); /* hash * 33 + c */
 | 
					        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 */
 | 
					/* And a case insensitive version */
 | 
				
			||||||
unsigned int dictGenCaseHashFunction(const unsigned char *buf, int len) {
 | 
					unsigned int dictGenCaseHashFunction(const unsigned char *buf, int len) {
 | 
				
			||||||
    unsigned int hash = 5381;
 | 
					    unsigned int hash = dict_hash_function_seed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (len--)
 | 
					    while (len--)
 | 
				
			||||||
        hash = ((hash << 5) + hash) + (tolower(*buf++)); /* hash * 33 + c */
 | 
					        hash = ((hash << 5) + hash) + (tolower(*buf++)); /* hash * 33 + c */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -162,6 +162,8 @@ void dictEnableResize(void);
 | 
				
			||||||
void dictDisableResize(void);
 | 
					void dictDisableResize(void);
 | 
				
			||||||
int dictRehash(dict *d, int n);
 | 
					int dictRehash(dict *d, int n);
 | 
				
			||||||
int dictRehashMilliseconds(dict *d, int ms);
 | 
					int dictRehashMilliseconds(dict *d, int ms);
 | 
				
			||||||
 | 
					void dictSetHashFunctionSeed(unsigned int initval);
 | 
				
			||||||
 | 
					unsigned int dictGetHashFunctionSeed(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Hash table types */
 | 
					/* Hash table types */
 | 
				
			||||||
extern dictType dictTypeHeapStringCopyKey;
 | 
					extern dictType dictTypeHeapStringCopyKey;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1080,8 +1080,6 @@ void initServer() {
 | 
				
			||||||
    scriptingInit();
 | 
					    scriptingInit();
 | 
				
			||||||
    slowlogInit();
 | 
					    slowlogInit();
 | 
				
			||||||
    bioInit();
 | 
					    bioInit();
 | 
				
			||||||
    srand(time(NULL)^getpid());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Populates the Redis Command Table starting from the hard coded list
 | 
					/* Populates the Redis Command Table starting from the hard coded list
 | 
				
			||||||
| 
						 | 
					@ -1959,9 +1957,15 @@ void setupSignalHandlers(void) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char **argv) {
 | 
					int main(int argc, char **argv) {
 | 
				
			||||||
    long long start;
 | 
					    long long start;
 | 
				
			||||||
 | 
					    struct timeval tv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* We need to initialize our libraries, and the server. */
 | 
				
			||||||
    zmalloc_enable_thread_safeness();
 | 
					    zmalloc_enable_thread_safeness();
 | 
				
			||||||
 | 
					    srand(time(NULL)^getpid());
 | 
				
			||||||
 | 
					    gettimeofday(&tv,NULL);
 | 
				
			||||||
 | 
					    dictSetHashFunctionSeed(tv.tv_sec^tv.tv_usec^getpid());
 | 
				
			||||||
    initServerConfig();
 | 
					    initServerConfig();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (argc >= 2) {
 | 
					    if (argc >= 2) {
 | 
				
			||||||
        int j = 1; /* First option to parse in argv[] */
 | 
					        int j = 1; /* First option to parse in argv[] */
 | 
				
			||||||
        sds options = sdsempty();
 | 
					        sds options = sdsempty();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue