avoid truncating a directory path when using snprintf(), but instead
detect and return an error. found and fixed by shm@netbsd.
This commit is contained in:
parent
681e9c9b00
commit
a212be1ee8
@ -3,6 +3,8 @@ $eterna: CHANGES,v 1.78 2011/11/18 01:25:11 mrg Exp $
|
||||
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 shm@netbsd.org
|
||||
|
||||
changes in bozohttpd 20140102:
|
||||
o update a few content types
|
||||
|
@ -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, const char *file)
|
||||
}
|
||||
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",
|
||||
|
@ -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 *request)
|
||||
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 *request, int *isindex)
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user