Ian Kent 3685ec
autofs-5.0.3 - fix interface config buffer size
Ian Kent 3685ec
Ian Kent 3685ec
From: Ian Kent <raven@themaw.net>
Ian Kent 3685ec
Ian Kent 3685ec
When getting the interface configuration information autofs uses a
Ian Kent 3685ec
fixed size buffer for the interface information. If there are many
Ian Kent 3685ec
interfaces this causes the check to fail.
Ian Kent 3685ec
---
Ian Kent 3685ec
Ian Kent 3685ec
 CHANGELOG            |    1 +
Ian Kent 3685ec
 modules/replicated.c |   51 ++++++++++++++++++++++++++++++++++++++++++--------
Ian Kent 3685ec
 2 files changed, 44 insertions(+), 8 deletions(-)
Ian Kent 3685ec
Ian Kent 3685ec
Ian Kent 3685ec
diff --git a/CHANGELOG b/CHANGELOG
Ian Kent 3685ec
index d2fe0a6..5b0f265 100644
Ian Kent 3685ec
--- a/CHANGELOG
Ian Kent 3685ec
+++ b/CHANGELOG
Ian Kent 3685ec
@@ -34,6 +34,7 @@
Ian Kent 3685ec
 - update replicated server selection documentation.
Ian Kent 3685ec
 - use /dev/urandom instead of /dev/random.
Ian Kent 3685ec
 - check for mtab pointing to /proc/mounts.
Ian Kent 3685ec
+- dynamically allocate interface config buffer.
Ian Kent 3685ec
  
Ian Kent 3685ec
 14/01/2008 autofs-5.0.3
Ian Kent 3685ec
 -----------------------
Ian Kent 3685ec
diff --git a/modules/replicated.c b/modules/replicated.c
Ian Kent 3685ec
index 362ab1b..ad1ede2 100644
Ian Kent 3685ec
--- a/modules/replicated.c
Ian Kent 3685ec
+++ b/modules/replicated.c
Ian Kent 3685ec
@@ -95,6 +95,41 @@ void seed_random(void)
Ian Kent 3685ec
 	return;
Ian Kent 3685ec
 }
Ian Kent 3685ec
 
Ian Kent 3685ec
+static int alloc_ifreq(struct ifconf *ifc, int sock)
Ian Kent 3685ec
+{
Ian Kent 3685ec
+	int ret, lastlen = 0, len = MAX_IFC_BUF;
Ian Kent 3685ec
+	char err_buf[MAX_ERR_BUF], *buf;
Ian Kent 3685ec
+
Ian Kent 3685ec
+	while (1) {
Ian Kent 3685ec
+		buf = malloc(len);
Ian Kent 3685ec
+		if (!buf) {
Ian Kent 3685ec
+			char *estr = strerror_r(errno, err_buf, MAX_ERR_BUF);
Ian Kent 3685ec
+			logerr("malloc: %s", estr);
Ian Kent 3685ec
+			return 0;
Ian Kent 3685ec
+		}
Ian Kent 3685ec
+
Ian Kent 3685ec
+		ifc->ifc_len = sizeof(buf);
Ian Kent 3685ec
+		ifc->ifc_req = (struct ifreq *) buf;
Ian Kent 3685ec
+
Ian Kent 3685ec
+		ret = ioctl(sock, SIOCGIFCONF, ifc);
Ian Kent 3685ec
+		if (ret == -1) {
Ian Kent 3685ec
+			char *estr = strerror_r(errno, err_buf, MAX_ERR_BUF);
Ian Kent 3685ec
+			logerr("ioctl: %s", estr);
Ian Kent 3685ec
+			free(buf);
Ian Kent 3685ec
+			return 0;
Ian Kent 3685ec
+		}
Ian Kent 3685ec
+
Ian Kent 3685ec
+		if (ifc->ifc_len == lastlen)
Ian Kent 3685ec
+			break;
Ian Kent 3685ec
+
Ian Kent 3685ec
+		lastlen = ifc->ifc_len;
Ian Kent 3685ec
+		len += MAX_IFC_BUF;
Ian Kent 3685ec
+		free(buf);
Ian Kent 3685ec
+	}
Ian Kent 3685ec
+
Ian Kent 3685ec
+	return 1;
Ian Kent 3685ec
+}
Ian Kent 3685ec
+
Ian Kent 3685ec
 static unsigned int get_proximity(const char *host_addr, int addr_len)
Ian Kent 3685ec
 {
Ian Kent 3685ec
 	struct sockaddr_in *msk_addr, *if_addr;
Ian Kent 3685ec
@@ -122,12 +157,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
Ian Kent 3685ec
 		fcntl(sock, F_SETFD, cl_flags);
Ian Kent 3685ec
 	}
Ian Kent 3685ec
 
Ian Kent 3685ec
-	ifc.ifc_len = sizeof(buf);
Ian Kent 3685ec
-	ifc.ifc_req = (struct ifreq *) buf;
Ian Kent 3685ec
-	ret = ioctl(sock, SIOCGIFCONF, &ifc;;
Ian Kent 3685ec
-	if (ret == -1) {
Ian Kent 3685ec
-		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
Ian Kent 3685ec
-		logerr("ioctl: %s", estr);
Ian Kent 3685ec
+	if (!alloc_ifreq(&ifc, sock)) {
Ian Kent 3685ec
 		close(sock);
Ian Kent 3685ec
 		return PROXIMITY_ERROR;
Ian Kent 3685ec
 	}
Ian Kent 3685ec
@@ -138,7 +168,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
Ian Kent 3685ec
 	i = 0;
Ian Kent 3685ec
 	ptr = (char *) &ifc.ifc_buf[0];
Ian Kent 3685ec
 
Ian Kent 3685ec
-	while (ptr < buf + ifc.ifc_len) {
Ian Kent 3685ec
+	while (ptr < (char *) ifc.ifc_req + ifc.ifc_len) {
Ian Kent 3685ec
 		ifr = (struct ifreq *) ptr;
Ian Kent 3685ec
 
Ian Kent 3685ec
 		switch (ifr->ifr_addr.sa_family) {
Ian Kent 3685ec
@@ -147,6 +177,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
Ian Kent 3685ec
 			ret = memcmp(&if_addr->sin_addr, hst_addr, addr_len);
Ian Kent 3685ec
 			if (!ret) {
Ian Kent 3685ec
 				close(sock);
Ian Kent 3685ec
+				free(ifc.ifc_req);
Ian Kent 3685ec
 				return PROXIMITY_LOCAL;
Ian Kent 3685ec
 			}
Ian Kent 3685ec
 			break;
Ian Kent 3685ec
@@ -162,7 +193,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
Ian Kent 3685ec
 	i = 0;
Ian Kent 3685ec
 	ptr = (char *) &ifc.ifc_buf[0];
Ian Kent 3685ec
 
Ian Kent 3685ec
-	while (ptr < buf + ifc.ifc_len) {
Ian Kent 3685ec
+	while (ptr < (char *) ifc.ifc_req + ifc.ifc_len) {
Ian Kent 3685ec
 		ifr = (struct ifreq *) ptr;
Ian Kent 3685ec
 
Ian Kent 3685ec
 		switch (ifr->ifr_addr.sa_family) {
Ian Kent 3685ec
@@ -178,6 +209,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
Ian Kent 3685ec
 				char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
Ian Kent 3685ec
 				logerr("ioctl: %s", estr);
Ian Kent 3685ec
 				close(sock);
Ian Kent 3685ec
+				free(ifc.ifc_req);
Ian Kent 3685ec
 				return PROXIMITY_ERROR;
Ian Kent 3685ec
 			}
Ian Kent 3685ec
 
Ian Kent 3685ec
@@ -186,6 +218,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
Ian Kent 3685ec
 
Ian Kent 3685ec
 			if ((ia & mask) == (ha & mask)) {
Ian Kent 3685ec
 				close(sock);
Ian Kent 3685ec
+				free(ifc.ifc_req);
Ian Kent 3685ec
 				return PROXIMITY_SUBNET;
Ian Kent 3685ec
 			}
Ian Kent 3685ec
 
Ian Kent 3685ec
@@ -208,6 +241,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
Ian Kent 3685ec
 
Ian Kent 3685ec
 			if ((ia & mask) == (ha & mask)) {
Ian Kent 3685ec
 				close(sock);
Ian Kent 3685ec
+				free(ifc.ifc_req);
Ian Kent 3685ec
 				return PROXIMITY_NET;
Ian Kent 3685ec
 			}
Ian Kent 3685ec
 			break;
Ian Kent 3685ec
@@ -221,6 +255,7 @@ static unsigned int get_proximity(const char *host_addr, int addr_len)
Ian Kent 3685ec
 	}
Ian Kent 3685ec
 
Ian Kent 3685ec
 	close(sock);
Ian Kent 3685ec
+	free(ifc.ifc_req);
Ian Kent 3685ec
 
Ian Kent 3685ec
 	return PROXIMITY_OTHER;
Ian Kent 3685ec
 }