git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jonathan Nieder <jrnieder@gmail.com>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>, Jeff King <peff@peff.net>,
	Eric Wong <normalperson@yhbt.net>,
	Erik Faye-Lund <kusmabite@gmail.com>
Subject: [PATCH 5/5] daemon: check for errors retrieving IP address
Date: Thu, 8 Mar 2012 07:11:53 -0600	[thread overview]
Message-ID: <20120308131153.GE9426@burratino> (raw)
In-Reply-To: <20120308124857.GA7666@burratino>

Date: Fri, 17 Jun 2011 05:26:05 -0500

To retrieve a canonical IP address for possible use in a
--interpolated-path=%IP string, the git daemon calls inet_ntop to fill
a buffer of size HOST_NAME_MAX+1, ignoring errors, and copies the
result.  If the address has length > HOST_NAME_MAX (which was as low
as 8 in ancient times) then inet_ntop could error out, leading the git
daemon to copy uninitialized data.

This probably never happens in practice because modern systems allow
such long hostnames as 64 chars (POSIX requires at least 255) or have
no compile-time maximum at all and let git fall back to a buffer size
of 256.  But it is more comforting not to rely on that.  So:

 - in "ipv4" code, which uses inet_ntop, use a buffer size of 64 (long
   enough to hold an ipv6 address if needed).

 - in ipv6 code, use the "getnameinfo" function that is already being
   used to convert addresses to text in error messages.  It uses a
   buffer of length NI_MAXHOST.

 - check for errors and make dns_ip_address() and git_locate_host()
   return NULL when they occur.  strbuf_expand_dict_cb treats NULL as
   an empty substitution string.

As a nice side effect, the fallback definition of HOST_NAME_MAX for
platforms that don't define it is no longer needed.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
This patch allows getnameinfo and inet_ntop to use a larger buffer or
fail.  (I was mostly nervous because HOST_NAME_MAX is not guaranteed
to be large enough to hold an IP address.)

That's the end of the series.  Thanks for reading.

 dns-ipv4.h |   11 +++++------
 dns-ipv6.c |   16 ++++++++--------
 tcp.c      |    6 ++++--
 3 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/dns-ipv4.h b/dns-ipv4.h
index 6803bcba..c5f1778f 100644
--- a/dns-ipv4.h
+++ b/dns-ipv4.h
@@ -1,9 +1,7 @@
 #ifndef DNS_IPV4_H
 #define DNS_IPV4_H
 
-#ifndef HOST_NAME_MAX
-#define HOST_NAME_MAX 256
-#endif
+#define ADDRBUFLEN 64	/* 46 for an ipv6 address, plus a little extra */
 
 struct ipv4_address {
 	char **ap;
@@ -33,9 +31,10 @@ static inline const char *dns_name(const resolved_address *addr)
 static inline char *dns_ip_address(const resolved_address *addr,
 					const resolver_result *ai)
 {
-	char addrbuf[HOST_NAME_MAX + 1];
-	inet_ntop(ai->he->h_addrtype, &addr->sa.sin_addr,
-		  addrbuf, sizeof(addrbuf));
+	char addrbuf[ADDRBUFLEN];
+	if (!inet_ntop(ai->he->h_addrtype, &addr->sa.sin_addr,
+		  addrbuf, sizeof(addrbuf)))
+		return NULL;
 	return xstrdup(addrbuf);
 }
 
diff --git a/dns-ipv6.c b/dns-ipv6.c
index ca59ff91..f2325681 100644
--- a/dns-ipv6.c
+++ b/dns-ipv6.c
@@ -1,8 +1,9 @@
 #include "cache.h"
 #include "dns-ipv6.h"
 
-#ifndef HOST_NAME_MAX
-#define HOST_NAME_MAX 256
+/* from RFC 2553 */
+#ifndef NI_MAXHOST
+#define NI_MAXHOST 1025
 #endif
 
 const char *dns_name(const resolved_address *i)
@@ -19,12 +20,11 @@ const char *dns_name(const resolved_address *i)
 char *dns_ip_address(const resolved_address *i, const resolver_result *ai0)
 {
 	const struct addrinfo *ai = *i;
-	char addrbuf[HOST_NAME_MAX + 1];
-	struct sockaddr_in *sin_addr;
-
-	sin_addr = (void *)ai->ai_addr;
-	inet_ntop(AF_INET, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf));
-	return xstrdup(addrbuf);
+	char addr[NI_MAXHOST];
+	if (getnameinfo(ai->ai_addr, ai->ai_addrlen, addr, sizeof(addr),
+			NULL, 0, NI_NUMERICHOST))
+		return NULL;
+	return xstrdup(addr);
 }
 
 int dns_resolve(const char *host, const char *port, int flags,
diff --git a/tcp.c b/tcp.c
index 4239daf3..83f0313a 100644
--- a/tcp.c
+++ b/tcp.c
@@ -56,8 +56,10 @@ void git_locate_host(const char *hostname, char **ip_address,
 		*ip_address = dns_ip_address(&i, &ai);
 
 		free(*canon_hostname);
-		*canon_hostname = xstrdup(dns_canonname(i, ai) ?
-					dns_canonname(i, ai) : *ip_address);
+		*canon_hostname =
+			dns_canonname(i, ai) ? xstrdup(dns_canonname(i, ai)) :
+			*ip_address ? xstrdup(*ip_address) :
+			NULL;
 		break;
 	}
 
-- 
1.7.9.2

  parent reply	other threads:[~2012-03-08 13:12 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-08 12:48 [PATCH 0/5] transport: unify ipv4 and ipv6 code paths Jonathan Nieder
2012-03-08 13:03 ` [PATCH 1/5] transport: expose git_tcp_connect() and friends in new tcp.h Jonathan Nieder
2012-03-08 15:28   ` Erik Faye-Lund
2012-03-08 13:05 ` [PATCH 2/5] daemon: make host resolution a separate function Jonathan Nieder
2012-03-08 13:06 ` [PATCH 3/5] daemon: move locate_host() to tcp lib Jonathan Nieder
2012-03-08 13:09 ` [PATCH 4/5] tcp: unify ipv4 and ipv6 code paths Jonathan Nieder
2012-03-08 15:39   ` Erik Faye-Lund
2012-03-08 21:10     ` Jonathan Nieder
2012-03-08 13:11 ` Jonathan Nieder [this message]
2012-03-08 13:16 ` [PATCH 6/5] tcp: make dns_resolve() return an error code Jonathan Nieder
2012-03-08 13:21 ` [PATCH 7/5] transport: optionally honor DNS SRV records Jonathan Nieder
2012-03-08 16:18   ` Erik Faye-Lund
2012-03-08 21:35     ` Jonathan Nieder
2012-03-09  7:07       ` Johannes Sixt
2012-03-09  8:00         ` Jonathan Nieder
2012-03-08 13:23 ` [PATCH 8/5] srv: tolerate broken DNS replies Jonathan Nieder
2012-03-08 22:28   ` Richard Hartmann
2012-06-11 18:12 ` [PATCH 0/5] transport: unify ipv4 and ipv6 code paths Erik Faye-Lund
2012-06-11 18:59   ` Junio C Hamano
2012-06-14  5:02   ` Jonathan Nieder

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120308131153.GE9426@burratino \
    --to=jrnieder@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=kusmabite@gmail.com \
    --cc=normalperson@yhbt.net \
    --cc=peff@peff.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).