It looks like connect.c waits too long before it uses errno in both copies of git_tcp_connect_sock. Both close and freeaddrinfo can poke any non-zero value in there.
M.
It looks like connect.c waits too long before it uses errno in both copies of git_tcp_connect_sock. Both close and freeaddrinfo can poke any non-zero value in there.
M.
[PATCH] Fix errno usage in connect.c
Dear diary, on Wed, Jun 28, 2006 at 06:56:12PM CEST, I got a letter where Morten Welinder <mwelinder@gmail.com> said that...
> It looks like connect.c waits too long before it uses errno in both copies > of git_tcp_connect_sock. Both close and freeaddrinfo can poke any > non-zero value in there.
Nice catch.
->8-
errno was used after it could've been modified by a subsequent library call. Spotted by Morten Welinder.
Signed-off-by: Petr Baudis <pasky@suse.cz> ---
connect.c | 18 ++++++++++++------ 1 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/connect.c b/connect.c index cb4656d..9a87bd9 100644 --- a/connect.c +++ b/connect.c @@ -328,7 +328,7 @@ #ifndef NO_IPV6 */ static int git_tcp_connect_sock(char *host) { - int sockfd = -1; + int sockfd = -1, saved_errno = 0; char *colon, *end; const char *port = STR(DEFAULT_GIT_PORT); struct addrinfo hints, *ai0, *ai; @@ -362,9 +362,12 @@ static int git_tcp_connect_sock(char *ho for (ai0 = ai; ai; ai = ai->ai_next) { sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (sockfd < 0) + if (sockfd < 0) { + saved_errno = errno; continue; + } if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) { + saved_errno = errno; close(sockfd); sockfd = -1; continue; @@ -375,7 +378,7 @@ static int git_tcp_connect_sock(char *ho freeaddrinfo(ai0); if (sockfd < 0) - die("unable to connect a socket (%s)", strerror(errno)); + die("unable to connect a socket (%s)", strerror(saved_errno)); return sockfd; } @@ -387,7 +390,7 @@ #else /* NO_IPV6 */ */ static int git_tcp_connect_sock(char *host) { - int sockfd = -1; + int sockfd = -1, saved_errno = 0; char *colon, *end; char *port = STR(DEFAULT_GIT_PORT), *ep; struct hostent *he; @@ -426,8 +429,10 @@ static int git_tcp_connect_sock(char *ho for (ap = he->h_addr_list; *ap; ap++) { sockfd = socket(he->h_addrtype, SOCK_STREAM, 0); - if (sockfd < 0) + if (sockfd < 0) { + saved_errno = errno; continue; + } memset(&sa, 0, sizeof sa); sa.sin_family = he->h_addrtype; @@ -435,6 +440,7 @@ static int git_tcp_connect_sock(char *ho memcpy(&sa.sin_addr, *ap, he->h_length); if (connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) { + saved_errno = errno; close(sockfd); sockfd = -1; continue; @@ -443,7 +449,7 @@ static int git_tcp_connect_sock(char *ho } if (sockfd < 0) - die("unable to connect a socket (%s)", strerror(errno)); + die("unable to connect a socket (%s)", strerror(saved_errno)); return sockfd; }
-- Petr "Pasky" Baudis Stuff: http://pasky.or.cz/ Snow falling on Perl. White noise covering line noise. Hides all the bugs too. -- J. Putnam
Re: [PATCH] Fix errno usage in connect.c
Petr Baudis <pasky@suse.cz> writes:
> Dear diary, on Wed, Jun 28, 2006 at 06:56:12PM CEST, I got a letter > where Morten Welinder <mwelinder@gmail.com> said that... >> It looks like connect.c waits too long before it uses errno in both copies >> of git_tcp_connect_sock. Both close and freeaddrinfo can poke any >> non-zero value in there. > > Nice catch. > > ->8- > > errno was used after it could've been modified by a subsequent library call. > Spotted by Morten Welinder. > > Signed-off-by: Petr Baudis <pasky@suse.cz>
Thanks.