diff options
author | Daniel Stenberg <daniel@haxx.se> | 2019-08-30 11:29:55 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2019-08-31 11:41:56 +0200 |
commit | 84ced9389e1a7f576812e0675b37056331c4dbcd (patch) | |
tree | 1a7b73484497f19b163c3fdba266ff7ab12193cc /lib | |
parent | cd68dfe8311c42f088ef082bfd90aeae65b9f589 (diff) | |
download | curl-84ced9389e1a7f576812e0675b37056331c4dbcd.tar.gz |
Curl_addr2string: take an addrlen argument too
This allows the function to figure out if a unix domain socket has a
file name or not associated with it! When a socket is created with
socketpair(), as done in the fuzzer testing, the path struct member is
uninitialized and must not be accessed.
Bug: https://crbug.com/oss-fuzz/16699
Closes #4283
Diffstat (limited to 'lib')
-rw-r--r-- | lib/connect.c | 30 | ||||
-rw-r--r-- | lib/connect.h | 3 | ||||
-rw-r--r-- | lib/vquic/ngtcp2.c | 3 |
3 files changed, 22 insertions, 14 deletions
diff --git a/lib/connect.c b/lib/connect.c index aec397296..79b8094e7 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -628,7 +628,8 @@ void Curl_persistconninfo(struct connectdata *conn) /* retrieves ip address and port from a sockaddr structure. note it calls Curl_inet_ntop which sets errno on fail, not SOCKERRNO. */ -bool Curl_addr2string(struct sockaddr *sa, char *addr, long *port) +bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, + char *addr, long *port) { struct sockaddr_in *si = NULL; #ifdef ENABLE_IPV6 @@ -636,6 +637,8 @@ bool Curl_addr2string(struct sockaddr *sa, char *addr, long *port) #endif #if defined(HAVE_SYS_UN_H) && defined(AF_UNIX) struct sockaddr_un *su = NULL; +#else + (void)salen; #endif switch(sa->sa_family) { @@ -661,8 +664,12 @@ bool Curl_addr2string(struct sockaddr *sa, char *addr, long *port) #endif #if defined(HAVE_SYS_UN_H) && defined(AF_UNIX) case AF_UNIX: - su = (struct sockaddr_un*)sa; - msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path); + if(salen > sizeof(sa_family_t)) { + su = (struct sockaddr_un*)sa; + msnprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path); + } + else + addr[0] = 0; /* socket with no name */ *port = 0; return TRUE; #endif @@ -690,10 +697,11 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) char buffer[STRERROR_LEN]; struct Curl_sockaddr_storage ssrem; struct Curl_sockaddr_storage ssloc; - curl_socklen_t len; + curl_socklen_t plen; + curl_socklen_t slen; #ifdef HAVE_GETPEERNAME - len = sizeof(struct Curl_sockaddr_storage); - if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) { + plen = sizeof(struct Curl_sockaddr_storage); + if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) { int error = SOCKERRNO; failf(data, "getpeername() failed with errno %d: %s", error, Curl_strerror(error, buffer, sizeof(buffer))); @@ -701,9 +709,9 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) } #endif #ifdef HAVE_GETSOCKNAME - len = sizeof(struct Curl_sockaddr_storage); + slen = sizeof(struct Curl_sockaddr_storage); memset(&ssloc, 0, sizeof(ssloc)); - if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) { + if(getsockname(sockfd, (struct sockaddr*) &ssloc, &slen)) { int error = SOCKERRNO; failf(data, "getsockname() failed with errno %d: %s", error, Curl_strerror(error, buffer, sizeof(buffer))); @@ -711,7 +719,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) } #endif #ifdef HAVE_GETPEERNAME - if(!Curl_addr2string((struct sockaddr*)&ssrem, + if(!Curl_addr2string((struct sockaddr*)&ssrem, plen, conn->primary_ip, &conn->primary_port)) { failf(data, "ssrem inet_ntop() failed with errno %d: %s", errno, Curl_strerror(errno, buffer, sizeof(buffer))); @@ -720,7 +728,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN); #endif #ifdef HAVE_GETSOCKNAME - if(!Curl_addr2string((struct sockaddr*)&ssloc, + if(!Curl_addr2string((struct sockaddr*)&ssloc, slen, conn->local_ip, &conn->local_port)) { failf(data, "ssloc inet_ntop() failed with errno %d: %s", errno, Curl_strerror(errno, buffer, sizeof(buffer))); @@ -1049,7 +1057,7 @@ static CURLcode singleipconnect(struct connectdata *conn, return CURLE_OK; /* store remote address and port used in this connection attempt */ - if(!Curl_addr2string((struct sockaddr*)&addr.sa_addr, + if(!Curl_addr2string((struct sockaddr*)&addr.sa_addr, addr.addrlen, ipaddress, &port)) { /* malformed address or bug in inet_ntop, try next address */ failf(data, "sa_addr inet_ntop() failed with errno %d: %s", diff --git a/lib/connect.h b/lib/connect.h index e44c4a701..b23085a98 100644 --- a/lib/connect.h +++ b/lib/connect.h @@ -51,7 +51,8 @@ timediff_t Curl_timeleft(struct Curl_easy *data, curl_socket_t Curl_getconnectinfo(struct Curl_easy *data, struct connectdata **connp); -bool Curl_addr2string(struct sockaddr *sa, char *addr, long *port); +bool Curl_addr2string(struct sockaddr *sa, curl_socklen_t salen, + char *addr, long *port); /* * Check if a connection seems to be alive. diff --git a/lib/vquic/ngtcp2.c b/lib/vquic/ngtcp2.c index d98be181c..6b3d53ee0 100644 --- a/lib/vquic/ngtcp2.c +++ b/lib/vquic/ngtcp2.c @@ -541,12 +541,11 @@ CURLcode Curl_quic_connect(struct connectdata *conn, uint8_t paramsbuf[64]; ngtcp2_transport_params params; ssize_t nwrite; - (void)addrlen; qs->conn = conn; /* extract the used address as a string */ - if(!Curl_addr2string((struct sockaddr*)addr, ipbuf, &port)) { + if(!Curl_addr2string((struct sockaddr*)addr, addrlen, ipbuf, &port)) { char buffer[STRERROR_LEN]; failf(data, "ssrem inet_ntop() failed with errno %d: %s", errno, Curl_strerror(errno, buffer, sizeof(buffer))); |