[apparmor] [PATCH] libapparmor: ENOENT should only signify label not found in label queries

Tyler Hicks tyhicks at canonical.com
Fri Aug 2 19:40:50 UTC 2013


When doing label queries with aa_query_label(), there are a number of
error conditions that can occur. Most of them indicate that the query
could not happen. That may be because the application provided invalid
input, memory allocation failed, the kernel doesn't support queries,
libapparmor and the kernel may be out of sync, etc.

However, there's one special error condition that stands out from the
rest. That is when the query was successful but the kernel was unable to
find the subject label of the query.

This is a special error condition because it would be useful for
applications that will be doing queries to do a test query during their
initialization stage to make sure that their queries, the current
version of libapparmor, and the current kernel can be expected to work
well together later during runtime. If the test query fails, depending
on the application's configuration, it may want to continue without
AppArmor mediation or it may want to exit right then and there.

The significance of ENOENT for these test queries is that the
application has no idea what a valid label may be in its early
initialization phase. It isn't aware of what profiles are loaded and no
other application has started talking to it. So, it will have to guess
at a label name (maybe "default"?) for its test query and it needs to
know if the query was successful even if the label doesn't exist.

This patch eliminates all potential return locations that may have errno
set to ENOENT, except for the write() that sets ENOENT when the label
isn't found.

Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
---
 libraries/libapparmor/src/kernel_interface.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/libraries/libapparmor/src/kernel_interface.c b/libraries/libapparmor/src/kernel_interface.c
index 34f9579..53961b2 100644
--- a/libraries/libapparmor/src/kernel_interface.c
+++ b/libraries/libapparmor/src/kernel_interface.c
@@ -684,7 +684,9 @@ static void aafs_access_init_once(void)
  * @audited: upon successful return, will be 1 if query should be audited and 0
  *           if not
  *
- * Returns: 0 on success else -1 and sets errno
+ * Returns: 0 on success else -1 and sets errno. If -1 is returned and errno is
+ *          ENOENT, the query was successful but the label in the query string
+ *          could not be found by the kernel.
  */
 int aa_query_label(uint32_t mask, char *query, size_t size, int *allowed,
 		   int *audited)
@@ -708,8 +710,11 @@ int aa_query_label(uint32_t mask, char *query, size_t size, int *allowed,
 	}
 
 	fd = open(aafs_access, O_RDWR);
-	if (fd == -1)
+	if (fd == -1) {
+		if (errno == ENOENT)
+			errno = EPROTONOSUPPORT;
 		return -1;
+	}
 
 	memcpy(query, AA_QUERY_CMD_LABEL, AA_QUERY_CMD_LABEL_SIZE);
 	errno = 0;
@@ -717,6 +722,12 @@ int aa_query_label(uint32_t mask, char *query, size_t size, int *allowed,
 	if (ret != size) {
 		if (ret >= 0)
 			errno = EPROTO;
+		/* IMPORTANT: This is the only valid place to return ENOENT. It
+		 * indicates that the label cannot be found by the kernel but
+		 * the query was successful. Applications may depend on this to
+		 * check if their query strings and aa_query_label() work with
+		 * the current kernel by doing a test query.
+		 */
 		return -1;
 	}
 
@@ -725,8 +736,7 @@ int aa_query_label(uint32_t mask, char *query, size_t size, int *allowed,
 	(void)close(fd);
 	errno = saved;
 	if (ret != QUERY_LABEL_REPLY_LEN) {
-		if (ret >= 0)
-			errno = EPROTO;
+		errno = EPROTO;
 		return -1;
 	}
 
-- 
1.8.3.2




More information about the AppArmor mailing list