mirror of
https://github.com/rofl0r/proxychains-ng.git
synced 2024-12-21 11:48:57 +00:00
fix potential double-close of file descriptors
in case of an error condition, both start_chain() and chain_step() were closing the fd to be acted upon, without setting it to -1, and the function calling them would close them again. this could affect multi-threaded applications that opened new fds between the first and the second close, invalidating those fds in the targeted app. patch loosely based on report and PR by @jhfrontz. closes #542
This commit is contained in:
parent
0279dda939
commit
1d0bc349eb
47
src/core.c
47
src/core.c
@ -462,8 +462,10 @@ static int start_chain(int *fd, proxy_data * pd, char *begin_mark) {
|
||||
error1:
|
||||
proxychains_write_log(TP " timeout\n");
|
||||
error:
|
||||
if(*fd != -1)
|
||||
if(*fd != -1) {
|
||||
close(*fd);
|
||||
*fd = -1;
|
||||
}
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
@ -520,9 +522,9 @@ static unsigned int calc_alive(proxy_data * pd, unsigned int proxy_count) {
|
||||
}
|
||||
|
||||
|
||||
static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
|
||||
static int chain_step(int *ns, proxy_data * pfrom, proxy_data * pto) {
|
||||
int retcode = -1;
|
||||
char *hostname;
|
||||
char *hostname, *errmsg = 0;
|
||||
char hostname_buf[MSG_LEN_MAX];
|
||||
char ip_buf[INET6_ADDRSTRLEN];
|
||||
int v6 = pto->ip.is_v6;
|
||||
@ -536,31 +538,34 @@ static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
|
||||
usenumericip:
|
||||
if(!inet_ntop(v6?AF_INET6:AF_INET,pto->ip.addr.v6,ip_buf,sizeof ip_buf)) {
|
||||
pto->ps = DOWN_STATE;
|
||||
proxychains_write_log("<--ip conversion error!\n");
|
||||
close(ns);
|
||||
return SOCKET_ERROR;
|
||||
errmsg = "<--ip conversion error!\n";
|
||||
retcode = SOCKET_ERROR;
|
||||
goto err;
|
||||
}
|
||||
hostname = ip_buf;
|
||||
}
|
||||
|
||||
proxychains_write_log(TP " %s:%d ", hostname, htons(pto->port));
|
||||
retcode = tunnel_to(ns, pto->ip, pto->port, pfrom->pt, pfrom->user, pfrom->pass);
|
||||
retcode = tunnel_to(*ns, pto->ip, pto->port, pfrom->pt, pfrom->user, pfrom->pass);
|
||||
switch (retcode) {
|
||||
case SUCCESS:
|
||||
pto->ps = BUSY_STATE;
|
||||
break;
|
||||
case BLOCKED:
|
||||
pto->ps = BLOCKED_STATE;
|
||||
proxychains_write_log("<--denied\n");
|
||||
close(ns);
|
||||
break;
|
||||
errmsg = "<--denied\n";
|
||||
goto err;
|
||||
case SOCKET_ERROR:
|
||||
pto->ps = DOWN_STATE;
|
||||
proxychains_write_log("<--socket error or timeout!\n");
|
||||
close(ns);
|
||||
break;
|
||||
errmsg = "<--socket error or timeout!\n";
|
||||
goto err;
|
||||
}
|
||||
return retcode;
|
||||
err:
|
||||
if(errmsg) proxychains_write_log(errmsg);
|
||||
if(*ns != -1) close(*ns);
|
||||
*ns = -1;
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int connect_proxy_chain(int sock, ip_type target_ip,
|
||||
@ -596,7 +601,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
||||
p2 = select_proxy(FIFOLY, pd, proxy_count, &offset);
|
||||
if(!p2)
|
||||
break;
|
||||
if(SUCCESS != chain_step(ns, p1, p2)) {
|
||||
if(SUCCESS != chain_step(&ns, p1, p2)) {
|
||||
PDEBUG("GOTO AGAIN 1\n");
|
||||
goto again;
|
||||
}
|
||||
@ -605,7 +610,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
||||
//proxychains_write_log(TP);
|
||||
p3->ip = target_ip;
|
||||
p3->port = target_port;
|
||||
if(SUCCESS != chain_step(ns, p1, p3))
|
||||
if(SUCCESS != chain_step(&ns, p1, p3))
|
||||
goto error;
|
||||
break;
|
||||
|
||||
@ -643,7 +648,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
||||
/* Try from the beginning to where we started */
|
||||
offset = 0;
|
||||
continue;
|
||||
} else if(SUCCESS != chain_step(ns, p1, p2)) {
|
||||
} else if(SUCCESS != chain_step(&ns, p1, p2)) {
|
||||
PDEBUG("GOTO AGAIN 1\n");
|
||||
goto again;
|
||||
} else
|
||||
@ -655,7 +660,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
||||
p3->port = target_port;
|
||||
proxychains_proxy_offset = offset+1;
|
||||
PDEBUG("pd_offset = %d, curr_len = %d\n", proxychains_proxy_offset, curr_len);
|
||||
if(SUCCESS != chain_step(ns, p1, p3))
|
||||
if(SUCCESS != chain_step(&ns, p1, p3))
|
||||
goto error;
|
||||
break;
|
||||
|
||||
@ -673,7 +678,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
||||
while(offset < proxy_count) {
|
||||
if(!(p2 = select_proxy(FIFOLY, pd, proxy_count, &offset)))
|
||||
break;
|
||||
if(SUCCESS != chain_step(ns, p1, p2)) {
|
||||
if(SUCCESS != chain_step(&ns, p1, p2)) {
|
||||
PDEBUG("chain_step failed\n");
|
||||
goto error_strict;
|
||||
}
|
||||
@ -682,7 +687,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
||||
//proxychains_write_log(TP);
|
||||
p3->ip = target_ip;
|
||||
p3->port = target_port;
|
||||
if(SUCCESS != chain_step(ns, p1, p3))
|
||||
if(SUCCESS != chain_step(&ns, p1, p3))
|
||||
goto error;
|
||||
break;
|
||||
|
||||
@ -698,7 +703,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
||||
while(++curr_len < max_chain) {
|
||||
if(!(p2 = select_proxy(RANDOMLY, pd, proxy_count, &offset)))
|
||||
goto error_more;
|
||||
if(SUCCESS != chain_step(ns, p1, p2)) {
|
||||
if(SUCCESS != chain_step(&ns, p1, p2)) {
|
||||
PDEBUG("GOTO AGAIN 2\n");
|
||||
goto again;
|
||||
}
|
||||
@ -707,7 +712,7 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
||||
//proxychains_write_log(TP);
|
||||
p3->ip = target_ip;
|
||||
p3->port = target_port;
|
||||
if(SUCCESS != chain_step(ns, p1, p3))
|
||||
if(SUCCESS != chain_step(&ns, p1, p3))
|
||||
goto error;
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user