proxy_gethostbyname: fix thread safety issues arising from ...

gethostent() usage.

also set hostent.h_aliases member to a valid pointer.
This commit is contained in:
rofl0r 2012-11-04 05:02:57 +01:00
parent b851b39a37
commit 2d58820635

View File

@ -737,6 +737,11 @@ int connect_proxy_chain(int sock, ip_type target_ip,
static const ip_type local_host = { {127, 0, 0, 1} }; static const ip_type local_host = { {127, 0, 0, 1} };
static void gethostbyname_data_setstring(struct gethostbyname_data* data, char* name) {
snprintf(data->addr_name, sizeof(data->addr_name), "%s", name);
data->hostent_space.h_name = data->addr_name;
}
struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data* data) { struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data* data) {
char buff[256]; char buff[256];
uint32_t i, hash; uint32_t i, hash;
@ -750,9 +755,12 @@ struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data*
data->resolved_addr_p[1] = NULL; data->resolved_addr_p[1] = NULL;
data->hostent_space.h_addr_list = data->resolved_addr_p; data->hostent_space.h_addr_list = data->resolved_addr_p;
// let aliases point to the NULL member, mimicking an empty list.
data->hostent_space.h_aliases = &data->resolved_addr_p[1];
data->resolved_addr = 0; data->resolved_addr = 0;
data->hostent_space.h_addrtype = AF_INET; data->hostent_space.h_addrtype = AF_INET;
data->hostent_space.h_length = sizeof(in_addr_t);
gethostname(buff, sizeof(buff)); gethostname(buff, sizeof(buff));
@ -760,19 +768,17 @@ struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data*
data->resolved_addr = inet_addr(buff); data->resolved_addr = inet_addr(buff);
if(data->resolved_addr == (in_addr_t) (-1)) if(data->resolved_addr == (in_addr_t) (-1))
data->resolved_addr = (in_addr_t) (local_host.as_int); data->resolved_addr = (in_addr_t) (local_host.as_int);
snprintf(data->addr_name, sizeof(data->addr_name), "%s", name); goto retname;
data->hostent_space.h_name = data->addr_name;
data->hostent_space.h_length = sizeof(in_addr_t);
return &data->hostent_space;
} }
memset(buff, 0, sizeof(buff)); memset(buff, 0, sizeof(buff));
// FIXME this is not threadsafe // this iterates over the "known hosts" db, usually /etc/hosts
while((hp = gethostent())) while((hp = gethostent()))
if(!strcmp(hp->h_name, name)) if(!strcmp(hp->h_name, name) && hp->h_addrtype == AF_INET && hp->h_length == sizeof(in_addr_t)) {
return hp; data->resolved_addr = *((in_addr_t*)(hp->h_addr_list[0]));
goto retname;
}
hash = dalias_hash((char *) name); hash = dalias_hash((char *) name);
@ -825,10 +831,10 @@ struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data*
MUTEX_UNLOCK(&internal_ips_lock); MUTEX_UNLOCK(&internal_ips_lock);
snprintf(data->addr_name, sizeof(data->addr_name), "%s", name); retname:
gethostbyname_data_setstring(data, (char*) name);
data->hostent_space.h_name = data->addr_name;
data->hostent_space.h_length = sizeof(in_addr_t);
return &data->hostent_space; return &data->hostent_space;
err_plus_unlock: err_plus_unlock: