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';