mirror of
https://github.com/rofl0r/proxychains-ng.git
synced 2025-01-03 13:32:42 +00:00
fix realloc and add a layer of threadsafety upon dns-list accesses
This commit is contained in:
parent
d5ae1f9202
commit
41e73ab58d
4
Makefile
4
Makefile
@ -16,8 +16,8 @@ SRCS = $(sort $(wildcard src/*.c))
|
|||||||
OBJS = $(SRCS:.c=.o)
|
OBJS = $(SRCS:.c=.o)
|
||||||
LOBJS = $(OBJS:.o=.lo)
|
LOBJS = $(OBJS:.o=.lo)
|
||||||
|
|
||||||
CFLAGS += -Wall -O0 -g -std=c99 -D_GNU_SOURCE -pipe
|
CFLAGS += -Wall -O0 -g -std=c99 -D_GNU_SOURCE -pipe -DTHREAD_SAFE
|
||||||
LDFLAGS = -shared -fPIC -ldl
|
LDFLAGS = -shared -fPIC -ldl -lpthread
|
||||||
INC =
|
INC =
|
||||||
PIC = -fPIC -O0
|
PIC = -fPIC -O0
|
||||||
AR = $(CROSS_COMPILE)ar
|
AR = $(CROSS_COMPILE)ar
|
||||||
|
68
src/core.c
68
src/core.c
@ -4,9 +4,9 @@
|
|||||||
begin : Tue May 14 2002
|
begin : Tue May 14 2002
|
||||||
copyright : netcreature (C) 2002
|
copyright : netcreature (C) 2002
|
||||||
email : netcreature@users.sourceforge.net
|
email : netcreature@users.sourceforge.net
|
||||||
***************************************************************************/
|
***************************************************************************
|
||||||
/* GPL */
|
* GPL *
|
||||||
/***************************************************************************
|
***************************************************************************
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
@ -33,6 +33,11 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#ifdef THREAD_SAFE
|
||||||
|
#include <pthread.h>
|
||||||
|
pthread_mutex_t internal_ips_lock;
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
@ -60,6 +65,20 @@ uint32_t index_from_internal_ip(ip_type internalip) {
|
|||||||
return ret;
|
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) {
|
in_addr_t make_internal_ip(uint32_t index) {
|
||||||
ip_type ret;
|
ip_type ret;
|
||||||
index++; // so we can start at .0.0.1
|
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
|
#ifdef DEBUG
|
||||||
PDEBUG("tunnel_to()\n");
|
PDEBUG("tunnel_to()\n");
|
||||||
#endif
|
#endif
|
||||||
uint32_t index = INVALID_INDEX;
|
|
||||||
char* dns_name = NULL;
|
char* dns_name = NULL;
|
||||||
size_t dns_len = 0;
|
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 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.)
|
// the results returned from gethostbyname et al.)
|
||||||
if(ip.octet[0] == 224) {
|
if(ip.octet[0] == 224) {
|
||||||
index = index_from_internal_ip(ip);
|
dns_name = string_from_internal_ip(ip);
|
||||||
if(index > internal_ips.counter) goto err;
|
|
||||||
dns_name = internal_ips.list[index]->string;
|
|
||||||
if(!dns_name) goto err;
|
if(!dns_name) goto err;
|
||||||
dns_len = strlen(dns_name);
|
dns_len = strlen(dns_name);
|
||||||
if(!dns_len) goto err;
|
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");
|
PDEBUG("chain_step()\n");
|
||||||
#endif
|
#endif
|
||||||
if(pto->ip.octet[0] == 224) {
|
if(pto->ip.octet[0] == 224) {
|
||||||
index = index_from_internal_ip(pto->ip);
|
hostname = string_from_internal_ip(pto->ip);
|
||||||
if(index < internal_ips.counter)
|
if(!hostname) goto usenumericip;
|
||||||
hostname = internal_ips.list[index]->string;
|
|
||||||
else goto usenumericip;
|
|
||||||
} else {
|
} else {
|
||||||
usenumericip:
|
usenumericip:
|
||||||
hostname = inet_ntoa(*(struct in_addr*)&pto->ip);
|
hostname = inet_ntoa(*(struct in_addr*)&pto->ip);
|
||||||
@ -722,7 +736,7 @@ error_strict:
|
|||||||
return -1;
|
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 struct hostent hostent_space;
|
||||||
static in_addr_t resolved_addr;
|
static in_addr_t resolved_addr;
|
||||||
static char* resolved_addr_p[2];
|
static char* resolved_addr_p[2];
|
||||||
@ -732,6 +746,7 @@ struct hostent* proxy_gethostbyname(const char *name)
|
|||||||
{
|
{
|
||||||
char buff[256];
|
char buff[256];
|
||||||
uint32_t i, hash;
|
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;
|
void* new_mem;
|
||||||
size_t l;
|
size_t l;
|
||||||
|
|
||||||
@ -762,35 +777,43 @@ struct hostent* proxy_gethostbyname(const char *name)
|
|||||||
|
|
||||||
hash = dalias_hash((char*) name);
|
hash = dalias_hash((char*) name);
|
||||||
|
|
||||||
|
#ifdef THREAD_SAFE
|
||||||
|
pthread_mutex_lock(&internal_ips_lock);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(internal_ips.counter) {
|
if(internal_ips.counter) {
|
||||||
for( i = 0; i < internal_ips.counter; i++) {
|
for( i = 0; i < internal_ips.counter; i++) {
|
||||||
if(internal_ips.list[i]->hash == hash) {
|
if(internal_ips.list[i]->hash == hash) {
|
||||||
resolved_addr = make_internal_ip(i);
|
resolved_addr = make_internal_ip(i);
|
||||||
|
printf("got cached ip for %s\n", name);
|
||||||
goto have_ip;
|
goto have_ip;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(internal_ips.capa < internal_ips.counter + 1) {
|
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) {
|
if(new_mem) {
|
||||||
internal_ips.capa += 16;
|
internal_ips.capa += 16;
|
||||||
internal_ips.list = new_mem;
|
internal_ips.list = new_mem;
|
||||||
} else {
|
} else {
|
||||||
oom:
|
oom:
|
||||||
proxychains_write_log("out of mem\n");
|
proxychains_write_log("out of mem\n");
|
||||||
goto err;
|
goto err_plus_unlock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resolved_addr = make_internal_ip(internal_ips.counter);
|
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);
|
l = strlen(name);
|
||||||
new_mem = malloc(sizeof(string_hash_tuple) + l + 1);
|
new_mem = malloc(sizeof(string_hash_tuple) + l + 1);
|
||||||
if(!new_mem)
|
if(!new_mem)
|
||||||
goto oom;
|
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] = new_mem;
|
||||||
internal_ips.list[internal_ips.counter]->hash = hash;
|
internal_ips.list[internal_ips.counter]->hash = hash;
|
||||||
internal_ips.list[internal_ips.counter]->string = (char*) new_mem + sizeof(string_hash_tuple);
|
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:
|
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_name = addr_name;
|
||||||
hostent_space.h_length = sizeof (in_addr_t);
|
hostent_space.h_length = sizeof (in_addr_t);
|
||||||
return &hostent_space;
|
return &hostent_space;
|
||||||
|
|
||||||
err_dns:
|
err_plus_unlock:
|
||||||
proxychains_write_log("|DNS-response|: %s does not exist\n", name);
|
#ifdef THREAD_SAFE
|
||||||
perror("err_dns");
|
pthread_mutex_unlock(&internal_ips_lock);
|
||||||
err:
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
int proxy_getaddrinfo(const char *node, const char *service,
|
int proxy_getaddrinfo(const char *node, const char *service,
|
||||||
|
@ -37,6 +37,10 @@ typedef struct {
|
|||||||
} internal_ip_lookup_table;
|
} internal_ip_lookup_table;
|
||||||
|
|
||||||
extern internal_ip_lookup_table internal_ips;
|
extern internal_ip_lookup_table internal_ips;
|
||||||
|
#ifdef THREAD_SAFE
|
||||||
|
#include <pthread.h>
|
||||||
|
extern pthread_mutex_t internal_ips_lock;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*error codes*/
|
/*error codes*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -62,6 +62,9 @@ static void init_lib(void);
|
|||||||
|
|
||||||
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");
|
proxychains_write_log(LOG_PREFIX "DLL init\n");
|
||||||
|
|
||||||
get_chain_data(proxychains_pd, &proxychains_proxy_count, &proxychains_ct);
|
get_chain_data(proxychains_pd, &proxychains_proxy_count, &proxychains_ct);
|
||||||
|
Loading…
Reference in New Issue
Block a user