File: 0006-daemon-check-for-errors-retrieving-IP-address.diff

package info (click to toggle)
git 1%3A2.1.4-2.1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 28,832 kB
  • sloc: ansic: 154,058; sh: 131,926; perl: 28,828; tcl: 21,269; python: 5,337; makefile: 3,509; lisp: 1,786; php: 120; asm: 98; csh: 45
file content (121 lines) | stat: -rw-r--r-- 3,861 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
From 0d3b7d5879b6e3f54349f5f742a2cbfe254e3f25 Mon Sep 17 00:00:00 2001
From: Jonathan Nieder <jrnieder@gmail.com>
Date: Fri, 17 Jun 2011 05:26:05 -0500
Subject: daemon: check for errors retrieving IP address

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>
---
 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 c63558b..6f70d63 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;
@@ -37,9 +35,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 2129136..0b0e060 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 d149b43..a3eb038 100644
--- a/tcp.c
+++ b/tcp.c
@@ -58,8 +58,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.8.5.3