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;

Reply via email to