Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 31 additions & 5 deletions apps/wolfsshd/configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,7 @@ static int HandleInclude(WOLFSSHD_CONFIG *conf, const char *value, int depth)

if (ret == WS_SUCCESS) {
if (!WOPENDIR(NULL, conf->heap, &d, path)) {
word32 fileCount = 0, i, j;
word32 fileCount = 0, fileFilled = 0, i, j;
char** fileNames = NULL;

/* Count up the number of files */
Expand All @@ -749,6 +749,12 @@ static int HandleInclude(WOLFSSHD_CONFIG *conf, const char *value, int depth)
if (fileNames == NULL) {
ret = WS_MEMORY_E;
}
else {
/* Zero so any slot not filled by the second pass
* (e.g. files removed from the directory between
* the two passes) is NULL rather than garbage. */
WMEMSET(fileNames, 0, fileCount * sizeof(char*));
}
}

if (ret == WS_SUCCESS) {
Expand All @@ -764,21 +770,33 @@ static int HandleInclude(WOLFSSHD_CONFIG *conf, const char *value, int depth)
if (dir->d_type != DT_DIR)
#endif
{
/* Duplicate the name; readdir() may reuse its
* dirent storage on the next call, so the
* pointer cannot be retained across the loop. */
char* nameCopy = WSTRDUP(dir->d_name, conf->heap,
DYNTYPE_PATH);
if (nameCopy == NULL) {
ret = WS_MEMORY_E;
break;
}
/* Insert in string order */
for (j = 0; j < i; j++) {
if (WSTRCMP(dir->d_name, fileNames[j])
< 0) {
if (WSTRCMP(nameCopy, fileNames[j]) < 0) {
WMEMMOVE(fileNames+j+1, fileNames+j,
(i - j)*sizeof(char*));
break;
}
}
fileNames[j] = dir->d_name;
fileNames[j] = nameCopy;
i++;
}
}
/* Only process slots actually filled by the second
* pass; the directory may have shrunk since the
* count pass. */
fileFilled = i;

for (i = 0; i < fileCount; i++) {
for (i = 0; ret == WS_SUCCESS && i < fileFilled; i++) {
/* Check if filename prefix matches */
if (prefixLen > 0) {
if ((int)WSTRLEN(fileNames[i]) <= prefixLen) {
Expand Down Expand Up @@ -817,6 +835,14 @@ static int HandleInclude(WOLFSSHD_CONFIG *conf, const char *value, int depth)
}
}

/* Free the duplicated names. fileFilled counts the
* slots actually populated, so every entry below it
* holds a valid pointer. */
for (i = 0; i < fileFilled; i++) {
if (fileNames[i] != NULL) {
WFREE(fileNames[i], conf->heap, DYNTYPE_PATH);
}
}
if (fileNames != NULL) {
WFREE(fileNames, conf->heap, DYNTYPE_PATH);
}
Expand Down
Loading