mirror of
				https://github.com/rofl0r/proxychains-ng.git
				synced 2025-11-04 00:56:03 +00:00 
			
		
		
		
	fix realloc and add a layer of threadsafety upon dns-list accesses
This commit is contained in:
		
							
								
								
									
										4
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								Makefile
									
									
									
									
									
								
							@@ -16,8 +16,8 @@ SRCS = $(sort $(wildcard src/*.c))
 | 
			
		||||
OBJS = $(SRCS:.c=.o)
 | 
			
		||||
LOBJS = $(OBJS:.o=.lo)
 | 
			
		||||
 | 
			
		||||
CFLAGS  += -Wall -O0 -g -std=c99 -D_GNU_SOURCE -pipe 
 | 
			
		||||
LDFLAGS = -shared -fPIC -ldl
 | 
			
		||||
CFLAGS  += -Wall -O0 -g -std=c99 -D_GNU_SOURCE -pipe -DTHREAD_SAFE
 | 
			
		||||
LDFLAGS = -shared -fPIC -ldl -lpthread
 | 
			
		||||
INC     = 
 | 
			
		||||
PIC     = -fPIC -O0
 | 
			
		||||
AR      = $(CROSS_COMPILE)ar
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										68
									
								
								src/core.c
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								src/core.c
									
									
									
									
									
								
							@@ -4,9 +4,9 @@
 | 
			
		||||
    begin                : Tue May 14 2002
 | 
			
		||||
    copyright            :  netcreature (C) 2002
 | 
			
		||||
    email                : netcreature@users.sourceforge.net
 | 
			
		||||
 ***************************************************************************/
 | 
			
		||||
/*     GPL */
 | 
			
		||||
/***************************************************************************
 | 
			
		||||
 ***************************************************************************
 | 
			
		||||
 *     GPL *
 | 
			
		||||
 ***************************************************************************
 | 
			
		||||
 *                                                                         *
 | 
			
		||||
 *   This program is free software; you can redistribute it and/or modify  *
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by  *
 | 
			
		||||
@@ -33,6 +33,11 @@
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#ifdef THREAD_SAFE
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
pthread_mutex_t internal_ips_lock;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "core.h"
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
@@ -60,6 +65,20 @@ uint32_t index_from_internal_ip(ip_type internalip) {
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char* string_from_internal_ip(ip_type internalip) {
 | 
			
		||||
	char* res = NULL;
 | 
			
		||||
#ifdef THREAD_SAFE
 | 
			
		||||
	pthread_mutex_lock(&internal_ips_lock);
 | 
			
		||||
#endif
 | 
			
		||||
	uint32_t index = index_from_internal_ip(internalip);
 | 
			
		||||
	if(index < internal_ips.counter)
 | 
			
		||||
		res = internal_ips.list[index]->string;
 | 
			
		||||
#ifdef THREAD_SAFE
 | 
			
		||||
	pthread_mutex_unlock(&internal_ips_lock);
 | 
			
		||||
#endif
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
in_addr_t make_internal_ip(uint32_t index) {
 | 
			
		||||
	ip_type ret;
 | 
			
		||||
	index++; // so we can start at .0.0.1
 | 
			
		||||
@@ -234,7 +253,6 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,ch
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	PDEBUG("tunnel_to()\n");
 | 
			
		||||
#endif	
 | 
			
		||||
	uint32_t index = INVALID_INDEX;
 | 
			
		||||
	char* dns_name = NULL;
 | 
			
		||||
	size_t dns_len = 0;
 | 
			
		||||
	
 | 
			
		||||
@@ -242,9 +260,7 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt,ch
 | 
			
		||||
	// the range 224-255.* is reserved, and it won't go outside (unless the app does some other stuff with
 | 
			
		||||
	// the results returned from gethostbyname et al.)
 | 
			
		||||
	if(ip.octet[0] == 224) {
 | 
			
		||||
		index = index_from_internal_ip(ip);
 | 
			
		||||
		if(index > internal_ips.counter) goto err;
 | 
			
		||||
		dns_name = internal_ips.list[index]->string;
 | 
			
		||||
		dns_name = string_from_internal_ip(ip);
 | 
			
		||||
		if(!dns_name) goto err;
 | 
			
		||||
		dns_len = strlen(dns_name);
 | 
			
		||||
		if(!dns_len) goto err;
 | 
			
		||||
@@ -560,10 +576,8 @@ static int chain_step(int ns, proxy_data *pfrom, proxy_data *pto)
 | 
			
		||||
	PDEBUG("chain_step()\n");
 | 
			
		||||
#endif
 | 
			
		||||
	if(pto->ip.octet[0] == 224) {
 | 
			
		||||
		index = index_from_internal_ip(pto->ip);
 | 
			
		||||
		if(index < internal_ips.counter)
 | 
			
		||||
			hostname = internal_ips.list[index]->string;
 | 
			
		||||
		else goto usenumericip;
 | 
			
		||||
		hostname = string_from_internal_ip(pto->ip);
 | 
			
		||||
		if(!hostname) goto usenumericip;
 | 
			
		||||
	} else {
 | 
			
		||||
		usenumericip:
 | 
			
		||||
		hostname = inet_ntoa(*(struct in_addr*)&pto->ip);
 | 
			
		||||
@@ -722,7 +736,7 @@ error_strict:
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// TODO: all those buffers aren't threadsafe, but since no memory allocation happens there shouldnt be any segfaults
 | 
			
		||||
static struct hostent hostent_space;
 | 
			
		||||
static in_addr_t resolved_addr;
 | 
			
		||||
static char* resolved_addr_p[2];
 | 
			
		||||
@@ -732,6 +746,7 @@ struct hostent* proxy_gethostbyname(const char *name)
 | 
			
		||||
{
 | 
			
		||||
	char buff[256];
 | 
			
		||||
	uint32_t i, hash;
 | 
			
		||||
	// yep, new_mem never gets freed. once you passed a fake ip to the client, you can't "retreat" it
 | 
			
		||||
	void* new_mem;
 | 
			
		||||
	size_t l;
 | 
			
		||||
 | 
			
		||||
@@ -762,35 +777,43 @@ struct hostent* proxy_gethostbyname(const char *name)
 | 
			
		||||
	
 | 
			
		||||
	hash = dalias_hash((char*) name);
 | 
			
		||||
	
 | 
			
		||||
#ifdef THREAD_SAFE
 | 
			
		||||
	pthread_mutex_lock(&internal_ips_lock);
 | 
			
		||||
#endif
 | 
			
		||||
	
 | 
			
		||||
	if(internal_ips.counter) {
 | 
			
		||||
		for( i = 0; i < internal_ips.counter; i++) {
 | 
			
		||||
			if(internal_ips.list[i]->hash == hash) {
 | 
			
		||||
				resolved_addr = make_internal_ip(i);
 | 
			
		||||
				printf("got cached ip for %s\n", name);
 | 
			
		||||
				goto have_ip;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if(internal_ips.capa < internal_ips.counter + 1) {
 | 
			
		||||
		new_mem = realloc(internal_ips.list, internal_ips.capa + 16);
 | 
			
		||||
		printf("realloc\n");
 | 
			
		||||
		new_mem = realloc(internal_ips.list, (internal_ips.capa + 16) * sizeof(void*));
 | 
			
		||||
		if(new_mem) {
 | 
			
		||||
			internal_ips.capa += 16;
 | 
			
		||||
			internal_ips.list = new_mem;
 | 
			
		||||
		} else {
 | 
			
		||||
			oom:
 | 
			
		||||
			proxychains_write_log("out of mem\n");
 | 
			
		||||
			goto err;
 | 
			
		||||
			goto err_plus_unlock;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	resolved_addr = make_internal_ip(internal_ips.counter);
 | 
			
		||||
	if(resolved_addr == (in_addr_t) -1) goto err;
 | 
			
		||||
	if(resolved_addr == (in_addr_t) -1) goto err_plus_unlock;
 | 
			
		||||
 | 
			
		||||
	l = strlen(name);
 | 
			
		||||
	new_mem = malloc(sizeof(string_hash_tuple) + l + 1);
 | 
			
		||||
	if(!new_mem) 
 | 
			
		||||
		goto oom;
 | 
			
		||||
	
 | 
			
		||||
	printf("creating new entry %d for ip of %s\n", (int) internal_ips.counter, name);
 | 
			
		||||
	
 | 
			
		||||
	internal_ips.list[internal_ips.counter] = new_mem;
 | 
			
		||||
	internal_ips.list[internal_ips.counter]->hash = hash;
 | 
			
		||||
	internal_ips.list[internal_ips.counter]->string = (char*) new_mem + sizeof(string_hash_tuple);
 | 
			
		||||
@@ -801,16 +824,21 @@ struct hostent* proxy_gethostbyname(const char *name)
 | 
			
		||||
	
 | 
			
		||||
	have_ip:
 | 
			
		||||
	
 | 
			
		||||
	//strncpy(addr_name, name, sizeof(addr_name));
 | 
			
		||||
#ifdef THREAD_SAFE
 | 
			
		||||
	pthread_mutex_unlock(&internal_ips_lock);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	strncpy(addr_name, name, sizeof(addr_name));
 | 
			
		||||
	
 | 
			
		||||
	hostent_space.h_name = addr_name;
 | 
			
		||||
	hostent_space.h_length = sizeof (in_addr_t);
 | 
			
		||||
	return &hostent_space;
 | 
			
		||||
 | 
			
		||||
err_dns:
 | 
			
		||||
	proxychains_write_log("|DNS-response|: %s does not exist\n", name);
 | 
			
		||||
	perror("err_dns");
 | 
			
		||||
err:
 | 
			
		||||
err_plus_unlock:
 | 
			
		||||
#ifdef THREAD_SAFE
 | 
			
		||||
	pthread_mutex_unlock(&internal_ips_lock);
 | 
			
		||||
#endif
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
int proxy_getaddrinfo(const char *node, const char *service,
 | 
			
		||||
 
 | 
			
		||||
@@ -37,6 +37,10 @@ typedef struct {
 | 
			
		||||
} internal_ip_lookup_table;
 | 
			
		||||
 | 
			
		||||
extern internal_ip_lookup_table internal_ips;
 | 
			
		||||
#ifdef THREAD_SAFE
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
extern pthread_mutex_t internal_ips_lock;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*error codes*/
 | 
			
		||||
typedef enum {
 | 
			
		||||
 
 | 
			
		||||
@@ -62,6 +62,9 @@ static void init_lib(void);
 | 
			
		||||
 | 
			
		||||
static void init_lib(void)
 | 
			
		||||
{
 | 
			
		||||
#ifdef THREAD_SAFE
 | 
			
		||||
	pthread_mutex_init(&internal_ips_lock, NULL);
 | 
			
		||||
#endif
 | 
			
		||||
	proxychains_write_log(LOG_PREFIX "DLL init\n");
 | 
			
		||||
	
 | 
			
		||||
	get_chain_data(proxychains_pd, &proxychains_proxy_count, &proxychains_ct);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user