mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-23 02:27:12 +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:
parent
ffb051db51
commit
ed1fd20aa9
@ -312,9 +312,10 @@ fail: \
|
|||||||
static ssize_t readdirfd(int dirfd, struct dirent ***out,
|
static ssize_t readdirfd(int dirfd, struct dirent ***out,
|
||||||
int (*dircmp)(const struct dirent **, const struct dirent **))
|
int (*dircmp)(const struct dirent **, const struct dirent **))
|
||||||
{
|
{
|
||||||
struct dirent **dents, *dent;
|
struct dirent **dents = NULL, *dent;
|
||||||
ssize_t n = 0;
|
ssize_t n = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
int save;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
|
|
||||||
*out = NULL;
|
*out = NULL;
|
||||||
@ -343,17 +344,21 @@ static ssize_t readdirfd(int dirfd, struct dirent ***out,
|
|||||||
rewinddir(dir);
|
rewinddir(dir);
|
||||||
|
|
||||||
dents = calloc(n, sizeof(struct dirent *));
|
dents = calloc(n, sizeof(struct dirent *));
|
||||||
|
if (!dents)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
for (i = 0; i < n; ) {
|
for (i = 0; i < n; ) {
|
||||||
if ((dent = readdir(dir)) == NULL) {
|
if ((dent = readdir(dir)) == NULL) {
|
||||||
PDEBUG("readdir of entry[%d] failed: %m\n", i);
|
PDEBUG("readdir of entry[%d] failed: %m\n", i);
|
||||||
n = -1;
|
goto fail;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
|
if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
dents[i] = malloc(sizeof(*dents[i]));
|
dents[i] = malloc(sizeof(*dents[i]));
|
||||||
|
if (!dents[i])
|
||||||
|
goto fail;
|
||||||
memcpy(dents[i], dent, sizeof(*dent));
|
memcpy(dents[i], dent, sizeof(*dent));
|
||||||
i++;
|
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);
|
qsort(dents, n, sizeof(*dent), (int (*)(const void *, const void *))dircmp);
|
||||||
|
|
||||||
*out = dents;
|
*out = dents;
|
||||||
|
|
||||||
out:
|
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
return n;
|
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,
|
int _aa_overlaydirat_for_each(int dirfd[], int n, void *data,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user