Module Name:    src
Committed By:   christos
Date:           Thu May  7 21:07:34 UTC 2009

Modified Files:
        src/dist/ipf/lib: load_http.c

Log Message:
- prevent buffer overflow from Maksymilian Arciemowicz (worst case was 1041
  characters and we allocated only 1024.
While here:
- use snprintf to prevent this from happening in the future.
- don't close fd twice on error.
- pass unsigned char to ctype.h functions.


To generate a diff of this commit:
cvs rdiff -u -r1.1.1.1 -r1.2 src/dist/ipf/lib/load_http.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/dist/ipf/lib/load_http.c
diff -u src/dist/ipf/lib/load_http.c:1.1.1.1 src/dist/ipf/lib/load_http.c:1.2
--- src/dist/ipf/lib/load_http.c:1.1.1.1	Sat Apr 14 16:17:31 2007
+++ src/dist/ipf/lib/load_http.c	Thu May  7 17:07:34 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: load_http.c,v 1.1.1.1 2007/04/14 20:17:31 martin Exp $	*/
+/*	$NetBSD: load_http.c,v 1.2 2009/05/07 21:07:34 christos Exp $	*/
 
 /*
  * Copyright (C) 2006 by Darren Reed.
@@ -17,7 +17,8 @@
 load_http(char *url)
 {
 	int fd, len, left, port, endhdr, removed;
-	char *s, *t, *u, buffer[1024], *myurl;
+	size_t rem;
+	char *s, *t, *u, buffer[2048], *myurl;
 	alist_t *a, *rtop, *rbot;
 	struct sockaddr_in sin;
 	struct hostent *host;
@@ -34,7 +35,11 @@
 	rtop = NULL;
 	rbot = NULL;
 
-	sprintf(buffer, "GET %s HTTP/1.0\r\n", url);
+	rem = sizeof(buffer);
+	left = snprintf(buffer, rem, "GET %s HTTP/1.0\r\n", url);
+	if (left < 0 || left > rem)
+		goto done;
+	rem -= left;
 
 	myurl = strdup(url);
 	if (myurl == NULL)
@@ -44,8 +49,7 @@
 	t = strchr(s, '/');
 	if (t == NULL) {
 		fprintf(stderr, "load_http has a malformed URL '%s'\n", url);
-		free(myurl);
-		return NULL;
+		goto done;
 	}
 	*t++ = '\0';
 
@@ -53,7 +57,10 @@
 	if (u != NULL)
 		s = u + 1;		/* AUTH */
 
-	sprintf(buffer + strlen(buffer), "Host: %s\r\n\r\n", s);
+	left = snprintf(buffer + left, rem, "Host: %s\r\n\r\n", s);
+	if (left < 0 || left > rem)
+		goto done;
+	rem -= left;
 
 	u = strchr(s, ':');
 	if (u != NULL) {
@@ -69,7 +76,7 @@
 	sin.sin_family = AF_INET;
 	sin.sin_port = htons(port);
 
-	if (isdigit(*s)) {
+	if (isdigit((unsigned char)*s)) {
 		if (inet_aton(s, &sin.sin_addr) == -1) {
 			goto done;
 		}
@@ -85,16 +92,12 @@
 	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;
@@ -144,16 +147,17 @@
 				break;
 
 			*t++ = '\0';
-			for (u = buffer; isdigit(*u) || (*u == '.'); u++)
-				;
+			for (u = buffer; isdigit((unsigned char)*u) ||
+			    (*u == '.'); u++)
+				continue;
 			if (*u == '/') {
 				char *slash;
 
 				slash = u;
 				u++;
-				while (isdigit(*u))
+				while (isdigit((unsigned char)*u))
 					u++;
-				if (!isspace(*u) && *u)
+				if (!isspace((unsigned char)*u) && *u)
 					u = slash;
 			}
 			*u = '\0';

Reply via email to