diff options
author | stas <stas@FreeBSD.org> | 2009-05-29 16:24:23 +0000 |
---|---|---|
committer | stas <stas@FreeBSD.org> | 2009-05-29 16:24:23 +0000 |
commit | b6666822bf294f95488fd0cea33197358ed95ef5 (patch) | |
tree | 7ab281e7c2db563af0b40775b014bdc1a5c06c4f /contrib/ipfilter/lib | |
parent | 7411c6484bcdda96f6318f8e6fe42becb1181734 (diff) | |
download | FreeBSD-src-b6666822bf294f95488fd0cea33197358ed95ef5.zip FreeBSD-src-b6666822bf294f95488fd0cea33197358ed95ef5.tar.gz |
- 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
Diffstat (limited to 'contrib/ipfilter/lib')
-rw-r--r-- | contrib/ipfilter/lib/load_http.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/contrib/ipfilter/lib/load_http.c b/contrib/ipfilter/lib/load_http.c index 164b8b4..38d0b67 100644 --- a/contrib/ipfilter/lib/load_http.c +++ b/contrib/ipfilter/lib/load_http.c @@ -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; |