Stat full path, allocate enough space

Not stat'ing the full path (just entry->d_name) strangely works on glibc/fedora
but fails on musl/alpine. Stat'ing the full path is the right thing to do,
anyways.

There was a heap corruption in `dirl_find_templ_dir` due not allocating enough
space for the terminating NULL in `path_buf`. This again only showed up in
musl/alpine.
This commit is contained in:
Armin Friedl 2020-08-31 06:42:23 +02:00
parent d06c37fbd5
commit 66558aa615
3 changed files with 24 additions and 19 deletions

2
data.c
View file

@ -55,7 +55,7 @@ data_send_dirlisting(int fd, const struct response *res)
} }
/* entry line */ /* entry line */
if ((ret = dirl_entry(fd, e[i], &templates))) { if ((ret = dirl_entry(fd, e[i], res, &templates))) {
goto cleanup; goto cleanup;
} }

17
dirl.c
View file

@ -86,7 +86,7 @@ html_escape(const char* src, char* dst, size_t dst_siz)
static char* static char*
dirl_find_templ_dir(const char* start_path) dirl_find_templ_dir(const char* start_path)
{ {
char* path_buf = calloc(sizeof(char), strlen(start_path)); char* path_buf = calloc(sizeof(char), strlen(start_path)+1);
strcat(path_buf, start_path); strcat(path_buf, start_path);
if (strlen(path_buf) > 1 && path_buf[strlen(path_buf) - 1] == '/') { if (strlen(path_buf) > 1 && path_buf[strlen(path_buf) - 1] == '/') {
@ -100,8 +100,8 @@ dirl_find_templ_dir(const char* start_path)
errno = 0; errno = 0;
while ((de = readdir(cur))) { while ((de = readdir(cur))) {
if (de->d_type == DT_REG) { if (de->d_type == DT_REG) {
if (strcmp(DIRL_HEADER, de->d_name) || strcmp(DIRL_ENTRY, de->d_name) || if (!strcmp(DIRL_HEADER, de->d_name) || !strcmp(DIRL_ENTRY, de->d_name) ||
strcmp(DIRL_FOOTER, de->d_name)) { !strcmp(DIRL_FOOTER, de->d_name)) {
closedir(cur); closedir(cur);
return path_buf; return path_buf;
} }
@ -182,13 +182,18 @@ dirl_header(int fd, const struct response* res, const struct dirl_templ* templ)
} }
enum status enum status
dirl_entry(int fd, const struct dirent* entry, const struct dirl_templ* templ) dirl_entry(int fd,
const struct dirent* entry,
const struct response* res,
const struct dirl_templ* templ)
{ {
struct stat stat_buf; struct stat stat_buf;
lstat(entry->d_name, &stat_buf); char* path_buf = calloc(sizeof(char), strlen(res->path)+strlen(entry->d_name));
strcat(path_buf, res->path);
strcat(path_buf, entry->d_name);
lstat(path_buf, &stat_buf);
char* nentry = calloc(sizeof(char), strlen(templ->entry) + 1); char* nentry = calloc(sizeof(char), strlen(templ->entry) + 1);
//strcat(nentry, templ->entry);
memcpy(nentry, templ->entry, strlen(templ->entry) + 1); memcpy(nentry, templ->entry, strlen(templ->entry) + 1);
/* Replace placeholder */ /* Replace placeholder */

2
dirl.h
View file

@ -82,7 +82,7 @@ dirl_header(int, const struct response*, const struct dirl_templ*);
/* Print entry into the response */ /* Print entry into the response */
enum status enum status
dirl_entry(int, const struct dirent*, const struct dirl_templ*); dirl_entry(int, const struct dirent*, const struct response*, const struct dirl_templ*);
/* Print footer into the response */ /* Print footer into the response */
enum status enum status