utils: Don't use access() to determine readability of profiles file

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@canonical.com>
Acked-by: Steve Beattie <steve@nxnw.org>
This commit is contained in:
Tyler Hicks 2015-06-22 10:14:14 -05:00
parent 140b88b818
commit b786c64b17

View file

@ -10,7 +10,7 @@
#
# ------------------------------------------------------------------
import re, os, sys
import re, os, sys, errno
def cmd_enabled():
'''Returns error code if AppArmor is not enabled'''
@ -85,14 +85,21 @@ def get_profiles():
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.")
try:
f = open(apparmor_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" % (apparmor_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):