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;
size_t allocated;
size_t i;
char buf[256];
const unsigned int BUFSIZE = 2*PATH_MAX;
char buf[BUFSIZE];
char fullpath[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
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, HEADER2);
sprintf(buf, "<h1>Directory listing for %s</h1>", url);
snprintf(buf, BUFSIZE, "<h1>Directory listing for %s</h1>", url);
strcat(result, buf);
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, "/");
sprintf(buf, " <a href=\"%s\">%s</a> /", fullpath, token);
snprintf(buf, BUFSIZE, " <a href=\"%s\">%s</a> /", fullpath, token);
strcat(result, buf);
}
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))
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);
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));
char *tmpresult = realloc(result, allocated * sizeof(char));
if(!tmpresult) {
@ -146,13 +150,11 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries, int up
result = tmpresult;
}
urlencode(entries[i].name, encName);
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);
} 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);
}
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)
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);
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));
char *tmpresult = realloc(result, allocated * sizeof(char));
if(!tmpresult) {
@ -185,13 +189,11 @@ char* gen_html(const char *url, struct Entry *entries, size_t numentries, int up
result = tmpresult;
}
urlencode(entries[i].name, encName);
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));
} 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));
}
strcat(result, buf);