[apparmor] [PATCH] utils: Don't use access() to determine readability of profiles file

Tyler Hicks tyhicks at canonical.com
Fri Jun 19 16:05:16 UTC 2015


LSMs, such as AppArmor, aren't consulted when a program calls access(2).
This can result in access(2) returning 0 but a subsequent open(2)
failing.

The aa-status utility was doing the access() -> open() sequence and we
became aware of a large number of tracebacks due to open() failing for
lack of permissions. This patch catches any IOError exceptions thrown by
open(). It continues to print the same error message as before when
access() failed but also prints that error message when AppArmor blocks
the open of the apparmorfs profiles file.

https://launchpad.net/bugs/1466768

Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
---
 utils/aa-status | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/utils/aa-status b/utils/aa-status
index 9a18285..d3dd551 100755
--- a/utils/aa-status
+++ b/utils/aa-status
@@ -10,7 +10,7 @@
 #
 # ------------------------------------------------------------------
 
-import re, os, sys
+import re, os, sys, errno
 
 def cmd_enabled():
     '''Returns error code if AppArmor is not enabled'''
@@ -84,15 +84,22 @@ def get_profiles():
         errormsg("apparmor filesystem is not mounted.")
         sys.exit(3)
 
-    apparmor_profiles = os.path.join(apparmorfs, "profiles")
-    if not os.access(apparmor_profiles, os.R_OK):
-        errormsg("You do not have enough privilege to read the profile set.")
+    profiles = os.path.join(apparmorfs, "profiles")
+    try:
+        f = open(profiles)
+    except IOError as e:
+        if e.errno == errno.EACCES:
+            errormsg("You do not have enough privilege to read the profile set.")
+        else:
+            errormsg("Could not open %s: %s" % (profiles, os.strerror(e.errno)))
         sys.exit(4)
 
-    for p in open(apparmor_profiles).readlines():
+    for p in f.readlines():
         match = re.search("^([^\(]+)\s+\((\w+)\)$", p)
         profiles[match.group(1)] = match.group(2)
 
+    f.close()
+
     return profiles
 
 def get_processes(profiles):
-- 
2.1.4




More information about the AppArmor mailing list