[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