NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
bin/56358: I suspect bozo may have a core dump
>Number: 56358
>Category: bin
>Synopsis: I suspect bozo may have a core dump
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Aug 12 08:50:00 +0000 2021
>Originator: parrott
>Release: -CURRENT
>Organization:
individual
>Environment:
9.2, I downloaded httpd from HEAD
>Description:
In dir-index-bozo.c, there is a lack of error checking for the call to scandir. If, for some reason, scandir returns -1, I believe what we would have is an out of bounds dereference of *de (that wording may not be right).
I couldn't prove this on my system, because the malloc in scandir doesn't just fail, the whole process gets killed, but perhaps other systems would be affected differently.
>How-To-Repeat:
>Fix:
Index: dir-index-bozo.c
===================================================================
RCS file: /cvsroot/src/libexec/httpd/dir-index-bozo.c,v
retrieving revision 1.34
diff -u -p -r1.34 dir-index-bozo.c
--- dir-index-bozo.c 15 Oct 2020 02:19:23 -0000 1.34
+++ dir-index-bozo.c 12 Aug 2021 08:29:38 -0000
@@ -56,7 +56,7 @@ bozo_dir_index(bozo_httpreq_t *request,
bozohttpd_t *httpd = request->hr_httpd;
struct stat sb;
struct dirent **de, **deo;
- DIR *dp;
+ //DIR *dp;
char buf[MAXPATHLEN];
char *file = NULL, *printname = NULL, *p;
int k, j, fd;
@@ -74,9 +74,19 @@ bozo_dir_index(bozo_httpreq_t *request,
dirpath = file;
}
debug((httpd, DEBUG_FAT, "bozo_dir_index: dirpath '%s'", dirpath));
+
+ /*
+ * Scrap opendir. It seems to me, that it would make sense, that,
+ * formerly, readdir was used in the loop below, but we can scandir
+ * here (before any output is generated) and run through the results
+ * in the loop. Otherwise, I don't see the purpose of opendir.
+ *
+ * Later: Use the select parameter to eliminate unwanted entries.
+ */
if (stat(dirpath, &sb) < 0 ||
- (dp = opendir(dirpath)) == NULL) {
- if (errno == EPERM)
+ //(dp = opendir(dirpath)) == NULL) {
+ (j = k = scandir(dirpath, &de, NULL, alphasort)) < 0) {
+ if (errno == EACCES)
bozo_http_error(httpd, 403, request,
"no permission to open directory");
else if (errno == ENOENT)
@@ -96,7 +106,7 @@ bozo_dir_index(bozo_httpreq_t *request,
bozo_flush(httpd, stdout);
if (request->hr_method == HTTP_HEAD) {
- closedir(dp);
+ //closedir(dp);
goto done;
}
@@ -113,7 +123,7 @@ bozo_dir_index(bozo_httpreq_t *request,
if (strcmp(printname, httpd->index_html) == 0)
strcpy(printname, "/"); /* is ``slashdir'' */
else
- *p = '\0'; /* strip unwanted ``index_html'' */
+ *p = '\0'; /* strip unwanted ``index_html'' */
}
if ((p = bozo_escape_html(httpd, printname)) != NULL) {
free(printname);
@@ -140,8 +150,7 @@ bozo_dir_index(bozo_httpreq_t *request,
"<tr><th>Name<th>Last modified<th align=right>Size\r\n"
"<tbody>\r\n");
- for (j = k = scandir(dirpath, &de, NULL, alphasort), deo = de;
- j--; de++) {
+ for (deo = de; j--; de++) {
int nostat = 0;
char *name = (*de)->d_name;
char *urlname, *htmlname;
@@ -186,7 +195,8 @@ bozo_dir_index(bozo_httpreq_t *request,
else {
unsigned long long len;
- strftime(buf, sizeof buf, "%d-%b-%Y %R", gmtime(&sb.st_mtime));
+ strftime(buf, sizeof buf, "%d-%b-%Y %R",
+ gmtime(&sb.st_mtime));
bozo_printf(httpd, "<td>%s", buf);
len = ((unsigned long long)sb.st_size + 1023) / 1024;
@@ -195,16 +205,19 @@ bozo_dir_index(bozo_httpreq_t *request,
bozo_printf(httpd, "\r\n");
}
- closedir(dp);
+ //closedir(dp);
while (k--)
free(deo[k]);
free(deo);
+
bozo_printf(httpd, "</table>\r\n");
+
if (httpd->dir_readme != NULL) {
if (httpd->dir_readme[0] == '/')
snprintf(buf, sizeof buf, "%s", httpd->dir_readme);
else
- snprintf(buf, sizeof buf, "%s/%s", dirpath, httpd->dir_readme);
+ snprintf(buf, sizeof buf, "%s/%s", dirpath,
+ httpd->dir_readme);
fd = open(buf, O_RDONLY);
if (fd != -1) {
bozo_flush(httpd, stdout);
Home |
Main Index |
Thread Index |
Old Index