[apparmor] [PATCH] parser: Fix return value of dirat_for_each()
Tyler Hicks
tyhicks at canonical.com
Wed Feb 25 18:01:33 UTC 2015
Seth pointed out that dirat_for_each() didn't correctly handle the
return value from readdir_r(). On error, it directly returns a positive
errno value. This would have resulted in that positive errno value being
returned, with an undefined errno value set, from dirat_for_each().
However, the dirat_for_each() documentation states that -1 is returned,
with errno set, on error.
This patch results in readdir_r()'s return value being handled
appropriately. In addition, it ensures that 0 is always returned on
success.
Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
Reported-by: Seth Arnold <seth.arnold at canonical.com>
---
parser/lib.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/parser/lib.c b/parser/lib.c
index c3657a8..85e39e0 100644
--- a/parser/lib.c
+++ b/parser/lib.c
@@ -62,9 +62,9 @@
int dirat_for_each(DIR *dir, const char *name, void *data,
int (* cb)(DIR *, const char *, struct stat *, void *))
{
- struct dirent *dirent = NULL, *ent;
+ struct dirent *dirent = NULL;
DIR *d = NULL;
- int error = 0;
+ int error;
if (!cb || (!dir && !name)) {
errno = EINVAL;
@@ -102,11 +102,19 @@ int dirat_for_each(DIR *dir, const char *name, void *data,
d = dir;
}
- for (error = readdir_r(d, dirent, &ent);
- error == 0 && ent != NULL;
- error = readdir_r(d, dirent, &ent)) {
+ for (;;) {
+ struct dirent *ent;
struct stat my_stat;
+ error = readdir_r(d, dirent, &ent);
+ if (error) {
+ PDEBUG("readdir_r failed");
+ errno = error; /* readdir_r directly returns an errno */
+ goto fail;
+ } else if (!ent) {
+ break;
+ }
+
if (strcmp(ent->d_name, ".") == 0 ||
strcmp(ent->d_name, "..") == 0)
continue;
@@ -126,7 +134,7 @@ int dirat_for_each(DIR *dir, const char *name, void *data,
closedir(d);
free(dirent);
- return error;
+ return 0;
fail:
error = errno;
--
2.1.0
More information about the AppArmor
mailing list