From 7ea9f80d3f31c85a4729854b47977e282632e6ed Mon Sep 17 00:00:00 2001 From: rofl0r Date: Fri, 25 Jun 2021 02:43:00 +0100 Subject: [PATCH] fix segfault in socks4 upstream with unresolvable hostname using a socks4 tor upstream with an .onion url resulted in gethostbyname() returning NULL and a subsequent segfault. not only did the code not check the return value of gethostbyname(), that resolver API itself isn't threadsafe. as pure SOCKS4 supports only IPv4 addresses, and the main SOCKS4 user to this date is tor, we just use SOCKS4a unconditionally and pass the hostname to the proxy without trying to do any local name resolving. i suspect in 2021 almost all SOCKS4 proxy servers in existence use SOCKS4a extension, but should i be wrong on this, i prefer issue reports to show up and implement plain SOCKS4 fallback only when i see it is actually used in practice. --- src/reqs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/reqs.c b/src/reqs.c index 977af6b..9016051 100644 --- a/src/reqs.c +++ b/src/reqs.c @@ -1244,7 +1244,6 @@ connect_to_upstream_proxy(struct conn_s *connptr, struct request_s *request) unsigned short port; size_t ulen, passlen; - struct hostent *host; struct upstream *cur_upstream = connptr->upstream_proxy; ulen = cur_upstream->ua.user ? strlen(cur_upstream->ua.user) : 0; @@ -1261,10 +1260,11 @@ connect_to_upstream_proxy(struct conn_s *connptr, struct request_s *request) buff[1] = 1; /* connect command */ port = htons(request->port); memcpy(&buff[2], &port, 2); /* dest port */ - host = gethostbyname(request->host); - memcpy(&buff[4], host->h_addr_list[0], 4); /* dest ip */ - buff[8] = 0; /* user */ - if (9 != safe_write(connptr->server_fd, buff, 9)) + memcpy(&buff[4], "\0\0\0\1" /* socks4a fake ip */ + "\0" /* user */, 5); + len = strlen(request->host); + memcpy(&buff[9], request->host, len+1); + if (9+len+1 != safe_write(connptr->server_fd, buff, 9+len+1)) return -1; if (8 != safe_read(connptr->server_fd, buff, 8)) return -1;