mirror of
				https://github.com/rofl0r/proxychains-ng.git
				synced 2025-11-04 00:56:03 +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:
		
							
								
								
									
										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;
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user