Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 May 2009 16:24:23 +0000 (UTC)
From:      Stanislav Sedov <stas@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r193043 - head/contrib/ipfilter/lib
Message-ID:  <200905291624.n4TGONLo080106@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: stas
Date: Fri May 29 16:24:23 2009
New Revision: 193043
URL: http://svn.freebsd.org/changeset/base/193043

Log:
  - Prevent buffer overflow in IPFilter's load_http function used to load
    ipfilter tables via http by the user-level ippool utility. Previously
    the 1024-byte buffer used to store a http request coudld easily overflow
    if the length of the hostname part of the url passes exceeded 496 bytes. [1]
  - Use snprintf to prevent possieble buffer overflows in future. [2]
  - Do not try to close the descriptor twice on failure. [2]
  
  Reported by:	Maksymilian Arciemowicz <cxib@securityreason.com> [1]
  Obtained from:	NetBSD CVS [2]
  MFC after:	2 weeks

Modified:
  head/contrib/ipfilter/lib/load_http.c

Modified: head/contrib/ipfilter/lib/load_http.c
==============================================================================
--- head/contrib/ipfilter/lib/load_http.c	Fri May 29 16:15:56 2009	(r193042)
+++ head/contrib/ipfilter/lib/load_http.c	Fri May 29 16:24:23 2009	(r193043)
@@ -14,11 +14,13 @@
 alist_t *
 load_http(char *url)
 {
-	int fd, len, left, port, endhdr, removed;
-	char *s, *t, *u, buffer[1024], *myurl;
+	char *s, *t, *u, buffer[1044], *myurl;
 	alist_t *a, *rtop, *rbot;
 	struct sockaddr_in sin;
 	struct hostent *host;
+	size_t avail;
+	int fd, len, left, port, endhdr, removed;
+	int error;
 
 	/*
 	 * More than this would just be absurd.
@@ -32,7 +34,14 @@ load_http(char *url)
 	rtop = NULL;
 	rbot = NULL;
 
-	sprintf(buffer, "GET %s HTTP/1.0\r\n", url);
+	avail = sizeof(buffer);
+	error = snprintf(buffer, avail, "GET %s HTTP/1.0\r\n", url);
+
+	/*
+	 * error is always less then avail due to the constraint on
+	 * the url length above.
+	 */
+	avail -= error;
 
 	myurl = strdup(url);
 	if (myurl == NULL)
@@ -51,7 +60,11 @@ load_http(char *url)
 	if (u != NULL)
 		s = u + 1;		/* AUTH */
 
-	sprintf(buffer + strlen(buffer), "Host: %s\r\n\r\n", s);
+	error = snprintf(buffer + strlen(buffer), avail, "Host: %s\r\n\r\n", s);
+	if (error >= avail) {
+		fprintf(stderr, "URL is too large: %s\n", url);
+		goto done;
+	}
 
 	u = strchr(s, ':');
 	if (u != NULL) {
@@ -83,16 +96,12 @@ load_http(char *url)
 	if (fd == -1)
 		goto done;
 
-	if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
-		close(fd);
+	if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) == -1)
 		goto done;
-	}
 
 	len = strlen(buffer);
-	if (write(fd, buffer, len) != len) {
-		close(fd);
+	if (write(fd, buffer, len) != len)
 		goto done;
-	}
 
 	s = buffer;
 	endhdr = 0;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905291624.n4TGONLo080106>