Module Name: src
Committed By: mrg
Date: Tue Jul 8 14:01:21 UTC 2014
Modified Files:
src/libexec/httpd: CHANGES auth-bozo.c bozohttpd.c
Log Message:
avoid truncating a directory path when using snprintf(), but instead
detect and return an error.
found and fixed by shm@netbsd.
To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 src/libexec/httpd/CHANGES
cvs rdiff -u -r1.12 -r1.13 src/libexec/httpd/auth-bozo.c
cvs rdiff -u -r1.52 -r1.53 src/libexec/httpd/bozohttpd.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/libexec/httpd/CHANGES
diff -u src/libexec/httpd/CHANGES:1.16 src/libexec/httpd/CHANGES:1.17
--- src/libexec/httpd/CHANGES:1.16 Sat May 17 05:50:46 2014
+++ src/libexec/httpd/CHANGES Tue Jul 8 14:01:21 2014
@@ -3,6 +3,8 @@ $eterna: CHANGES,v 1.78 2011/11/18 01:25
changes in bozohttpd 20140201:
o support .svg files
o fix a core dump when requests timeout
+ o fix a security issue in basic HTTP authentication which would allow
+ authentication to be bypassed, from [email protected]
changes in bozohttpd 20140102:
o update a few content types
Index: src/libexec/httpd/auth-bozo.c
diff -u src/libexec/httpd/auth-bozo.c:1.12 src/libexec/httpd/auth-bozo.c:1.13
--- src/libexec/httpd/auth-bozo.c:1.12 Thu Jan 2 08:21:38 2014
+++ src/libexec/httpd/auth-bozo.c Tue Jul 8 14:01:21 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: auth-bozo.c,v 1.12 2014/01/02 08:21:38 mrg Exp $ */
+/* $NetBSD: auth-bozo.c,v 1.13 2014/07/08 14:01:21 mrg Exp $ */
/* $eterna: auth-bozo.c,v 1.17 2011/11/18 09:21:15 mrg Exp $ */
@@ -74,7 +74,11 @@ bozo_auth_check(bozo_httpreq_t *request,
}
request->hr_authrealm = bozostrdup(httpd, dir);
- snprintf(authfile, sizeof(authfile), "%s/%s", dir, AUTH_FILE);
+ if ((size_t)snprintf(authfile, sizeof(authfile), "%s/%s", dir, AUTH_FILE) >=
+ sizeof(authfile)) {
+ return bozo_http_error(httpd, 404, request,
+ "authfile path too long");
+ }
if (stat(authfile, &sb) < 0) {
debug((httpd, DEBUG_NORMAL,
"bozo_auth_check realm `%s' dir `%s' authfile `%s' missing",
Index: src/libexec/httpd/bozohttpd.c
diff -u src/libexec/httpd/bozohttpd.c:1.52 src/libexec/httpd/bozohttpd.c:1.53
--- src/libexec/httpd/bozohttpd.c:1.52 Wed Jul 2 13:58:09 2014
+++ src/libexec/httpd/bozohttpd.c Tue Jul 8 14:01:21 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: bozohttpd.c,v 1.52 2014/07/02 13:58:09 shm Exp $ */
+/* $NetBSD: bozohttpd.c,v 1.53 2014/07/08 14:01:21 mrg Exp $ */
/* $eterna: bozohttpd.c,v 1.178 2011/11/18 09:21:15 mrg Exp $ */
@@ -935,7 +935,12 @@ check_direct_access(bozo_httpreq_t *requ
bozo_check_special_files(request, basename);
}
- snprintf(dirfile, sizeof(dirfile), "%s/%s", dir, DIRECT_ACCESS_FILE);
+ if ((size_t)snprintf(dirfile, sizeof(dirfile), "%s/%s", dir,
+ DIRECT_ACCESS_FILE) >= sizeof(dirfile)) {
+ bozo_http_error(request->hr_httpd, 404, request,
+ "directfile path too long");
+ return 0;
+ }
if (stat(dirfile, &sb) < 0 ||
(fp = fopen(dirfile, "r")) == NULL)
return 0;
@@ -1127,7 +1132,7 @@ use_slashdir:
/*
* checks to see if this request has a valid .bzredirect file. returns
* 0 when no redirection happend, or 1 when handle_redirect() has been
- * called.
+ * called, -1 on error.
*/
static int
check_bzredirect(bozo_httpreq_t *request)
@@ -1142,7 +1147,12 @@ check_bzredirect(bozo_httpreq_t *request
* if this pathname is really a directory, but doesn't end in /,
* use it as the directory to look for the redir file.
*/
- snprintf(dir, sizeof(dir), "%s", request->hr_file + 1);
+ if((size_t)snprintf(dir, sizeof(dir), "%s", request->hr_file + 1) >=
+ sizeof(dir)) {
+ bozo_http_error(request->hr_httpd, 404, request,
+ "file path too long");
+ return -1;
+ }
debug((request->hr_httpd, DEBUG_FAT, "check_bzredirect: dir %s", dir));
basename = strrchr(dir, '/');
@@ -1156,13 +1166,23 @@ check_bzredirect(bozo_httpreq_t *request
bozo_check_special_files(request, basename);
}
- snprintf(redir, sizeof(redir), "%s/%s", dir, REDIRECT_FILE);
+ if ((size_t)snprintf(redir, sizeof(redir), "%s/%s", dir,
+ REDIRECT_FILE) >= sizeof(redir)) {
+ bozo_http_error(request->hr_httpd, 404, request,
+ "redirectfile path too long");
+ return -1;
+ }
if (lstat(redir, &sb) == 0) {
if (!S_ISLNK(sb.st_mode))
return 0;
absolute = 0;
} else {
- snprintf(redir, sizeof(redir), "%s/%s", dir, ABSREDIRECT_FILE);
+ if((size_t)snprintf(redir, sizeof(redir), "%s/%s", dir,
+ ABSREDIRECT_FILE) >= sizeof(redir)) {
+ bozo_http_error(request->hr_httpd, 404, request,
+ "redirectfile path too long");
+ return -1;
+ }
if (lstat(redir, &sb) < 0 || !S_ISLNK(sb.st_mode))
return 0;
absolute = 1;
@@ -1186,9 +1206,14 @@ check_bzredirect(bozo_httpreq_t *request
/* now we have the link pointer, redirect to the real place */
if (absolute)
finalredir = redirpath;
- else
- snprintf(finalredir = redir, sizeof(redir), "/%s/%s", dir,
- redirpath);
+ else {
+ if ((size_t)snprintf(finalredir = redir, sizeof(redir), "/%s/%s",
+ dir, redirpath) >= sizeof(redir)) {
+ bozo_http_error(request->hr_httpd, 404, request,
+ "redirect path too long");
+ return -1;
+ }
+ }
debug((request->hr_httpd, DEBUG_FAT,
"check_bzredirect: new redir %s", finalredir));
@@ -1307,8 +1332,12 @@ transform_request(bozo_httpreq_t *reques
goto bad_done;
}
- if (check_bzredirect(request))
+ switch(check_bzredirect(request)) {
+ case -1:
+ goto bad_done;
+ case 1:
return 0;
+ }
if (httpd->untrustedref) {
int to_indexhtml = 0;