2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-22 18:17:09 +00:00

libapparmor: fix readdirfd to memory checks and cleanup on failure

The open-coded readdirfd fn used to replace scandirat skipped
checks for memory allocation failures and cleaning on faulures,
fix this.

Acked-by: Tyler Hicks <tyhicks@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
(cherry picked from commit 25f98537dbe46599d22949a92a814b0533d5a4d0)
This commit is contained in:
John Johansen 2018-09-12 15:46:32 -07:00
parent ffb051db51
commit ed1fd20aa9

View File

@ -312,9 +312,10 @@ fail: \
static ssize_t readdirfd(int dirfd, struct dirent ***out,
int (*dircmp)(const struct dirent **, const struct dirent **))
{
struct dirent **dents, *dent;
struct dirent **dents = NULL, *dent;
ssize_t n = 0;
size_t i;
int save;
DIR *dir;
*out = NULL;
@ -343,17 +344,21 @@ static ssize_t readdirfd(int dirfd, struct dirent ***out,
rewinddir(dir);
dents = calloc(n, sizeof(struct dirent *));
if (!dents)
goto fail;
for (i = 0; i < n; ) {
if ((dent = readdir(dir)) == NULL) {
PDEBUG("readdir of entry[%d] failed: %m\n", i);
n = -1;
goto out;
goto fail;
}
if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
continue;
dents[i] = malloc(sizeof(*dents[i]));
if (!dents[i])
goto fail;
memcpy(dents[i], dent, sizeof(*dent));
i++;
}
@ -362,10 +367,19 @@ static ssize_t readdirfd(int dirfd, struct dirent ***out,
qsort(dents, n, sizeof(*dent), (int (*)(const void *, const void *))dircmp);
*out = dents;
out:
closedir(dir);
return n;
fail:
save = errno;
if (dents) {
for (i = 0; i < n; i++)
free(dents[i]);
}
free(dents);
closedir(dir);
errno = save;
return -1;
}
int _aa_overlaydirat_for_each(int dirfd[], int n, void *data,