Fixed some critical buffer overflows in dirlisting

This commit is contained in:
Thomas Kolb 2013-08-21 17:47:21 +02:00
parent e5d57be8ad
commit 88c5715293

View file

@ -67,7 +67,9 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries, int up
char *result; char *result;
size_t allocated; size_t allocated;
size_t i; size_t i;
char buf[256];
const unsigned int BUFSIZE = 2*PATH_MAX;
char buf[BUFSIZE];
char fullpath[PATH_MAX]; char fullpath[PATH_MAX];
char encName[2*PATH_MAX]; char encName[2*PATH_MAX];
@ -80,12 +82,12 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries, int up
// this is still safe // this is still safe
strcat(result, HEADER1); strcat(result, HEADER1);
sprintf(buf, "<title>Directory listing for %s</title>", url); snprintf(buf, BUFSIZE, "<title>Directory listing for %s</title>", url);
strcat(result, buf); strcat(result, buf);
strcat(result, HEADER2); strcat(result, HEADER2);
sprintf(buf, "<h1>Directory listing for %s</h1>", url); snprintf(buf, BUFSIZE, "<h1>Directory listing for %s</h1>", url);
strcat(result, buf); strcat(result, buf);
int isrootdir = strcmp(url, "/") == 0; int isrootdir = strcmp(url, "/") == 0;
@ -112,7 +114,7 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries, int up
strcat(fullpath, token); strcat(fullpath, token);
strcat(fullpath, "/"); strcat(fullpath, "/");
sprintf(buf, " <a href=\"%s\">%s</a> /", fullpath, token); snprintf(buf, BUFSIZE, " <a href=\"%s\">%s</a> /", fullpath, token);
strcat(result, buf); strcat(result, buf);
} }
while((token = strtok(NULL, "/")) != NULL); while((token = strtok(NULL, "/")) != NULL);
@ -131,11 +133,13 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries, int up
if(!(entries[i].flags & FLG_ISDIR)) if(!(entries[i].flags & FLG_ISDIR))
continue; continue;
size_t entrylen = 32 + 2 * strlen(entries[i].name); urlencode(entries[i].name, encName);
size_t entrylen = 64 + strlen(url) + strlen(entries[i].name) + strlen(encName);
size_t resultlen = strlen(result); size_t resultlen = strlen(result);
if(allocated < resultlen + entrylen) { if(allocated < resultlen + entrylen) {
allocated *= 2; allocated = 2*allocated + entrylen; // be on the safe side
LOG(LVL_DEBUG, "reallocating result string (subdirs) - new size: %lu bytes", allocated * sizeof(char)); LOG(LVL_DEBUG, "reallocating result string (subdirs) - new size: %lu bytes", allocated * sizeof(char));
char *tmpresult = realloc(result, allocated * sizeof(char)); char *tmpresult = realloc(result, allocated * sizeof(char));
if(!tmpresult) { if(!tmpresult) {
@ -146,13 +150,11 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries, int up
result = tmpresult; result = tmpresult;
} }
urlencode(entries[i].name, encName);
if(isrootdir) { if(isrootdir) {
sprintf(buf, "<li><a href=\"/%s/\">%s/</a></li>\n", snprintf(buf, BUFSIZE, "<li><a href=\"/%s/\">%s/</a></li>\n",
encName, entries[i].name); encName, entries[i].name);
} else { } else {
sprintf(buf, "<li><a href=\"%s/%s/\">%s/</a></li>\n", snprintf(buf, BUFSIZE, "<li><a href=\"%s/%s/\">%s/</a></li>\n",
url, encName, entries[i].name); url, encName, entries[i].name);
} }
strcat(result, buf); strcat(result, buf);
@ -170,11 +172,13 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries, int up
if(entries[i].flags & FLG_ISDIR) if(entries[i].flags & FLG_ISDIR)
continue; continue;
size_t entrylen = 64 + 2 * strlen(entries[i].name); urlencode(entries[i].name, encName);
size_t entrylen = 64 + strlen(url) + strlen(entries[i].name) + strlen(encName);
size_t resultlen = strlen(result); size_t resultlen = strlen(result);
if(allocated < resultlen + entrylen) { if(allocated < resultlen + entrylen) {
allocated *= 2; allocated = 2*allocated + entrylen; // be on the safe side
LOG(LVL_DEBUG, "reallocating result string (files) - new size: %lu bytes", allocated * sizeof(char)); LOG(LVL_DEBUG, "reallocating result string (files) - new size: %lu bytes", allocated * sizeof(char));
char *tmpresult = realloc(result, allocated * sizeof(char)); char *tmpresult = realloc(result, allocated * sizeof(char));
if(!tmpresult) { if(!tmpresult) {
@ -185,13 +189,11 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries, int up
result = tmpresult; result = tmpresult;
} }
urlencode(entries[i].name, encName);
if(isrootdir) { if(isrootdir) {
sprintf(buf, "<li><a href=\"/%s\">%s</a> [%s]</li>\n", snprintf(buf, BUFSIZE, "<li><a href=\"/%s\">%s</a> [%s]</li>\n",
encName, entries[i].name, format_size(entries[i].size)); encName, entries[i].name, format_size(entries[i].size));
} else { } else {
sprintf(buf, "<li><a href=\"%s/%s\">%s</a> [%s]</li>\n", snprintf(buf, BUFSIZE, "<li><a href=\"%s/%s\">%s</a> [%s]</li>\n",
url, encName, entries[i].name, format_size(entries[i].size)); url, encName, entries[i].name, format_size(entries[i].size));
} }
strcat(result, buf); strcat(result, buf);