Hello,

this patch fixes the minitools (aa-audit, aa-complain, aa-enforce, 
aa-autodep) to work with multiple profiles at once.

The "trick" to fix the minitools is to call read_profiles() outside of 
the for loop.

References: https://bugs.launchpad.net/apparmor/+bug/1378095


Note: aa-autodep will still crash in one special case - reproducer:
- copy the sshd profile from the "inactive" dir to /etc/apparmor.d/
  (important: the profile has to contain hats!)
- run aa-autodep with multiple parameters:
      aa-autodep /bin/true /bin/false
but that's a) rare and b) something for another patch (or bugreport) ;-)
(basically this is caused by read_inactive_profiles() running multiple 
times [1])


BTW: the minitools and tools.py probably need some other changes:
- a parameter to disable reloading/unloading the profile would be nice
- maybe reloading/unloading should be disabled by default if -d was given?
- the read_profiles() call can probably be moved to __init__()
- some command-specific tasks should be moved from __init__() to the
  respective cmd_*() function
- some of the cmd_*() function share lots of code and can probably be
  merged without too many if blocks
but that's unrelated to this patch ;-)


I propose this patch for trunk and the 2.9 branch.


[ tools-fix-multi-profile.diff ]

=== modified file 'utils/apparmor/tools.py'
--- utils/apparmor/tools.py     2014-10-07 13:06:01 +0000
+++ utils/apparmor/tools.py     2015-02-20 21:55:40 +0000
@@ -83,12 +83,12 @@
             yield (program, profile)
 
     def act(self):
+        apparmor.read_profiles()
+
         for (program, profile) in self.get_next_to_profile():
             if program is None:
                 program = profile
 
-            apparmor.read_profiles()
-
             if not program or not(os.path.exists(program) or 
apparmor.profile_exists(program)):
                 if program and not program.startswith('/'):
                     program = aaui.UI_GetString(_('The given program cannot be 
found, please try with the fully qualified path name of the program: '), '')
@@ -148,9 +148,10 @@
                 raise apparmor.AppArmorException(cmd_info[1])
 
     def cmd_enforce(self):
+        apparmor.read_profiles()
+
         for (program, profile) in self.get_next_to_profile():
 
-            apparmor.read_profiles()
             output_name = profile if program is None else program
 
             if not os.path.isfile(profile) or 
apparmor.is_skippable_file(profile):
@@ -166,9 +167,10 @@
                 raise apparmor.AppArmorException(cmd_info[1])
 
     def cmd_complain(self):
+        apparmor.read_profiles()
+
         for (program, profile) in self.get_next_to_profile():
 
-            apparmor.read_profiles()
             output_name = profile if program is None else program
 
             if not os.path.isfile(profile) or 
apparmor.is_skippable_file(profile):
@@ -184,9 +186,10 @@
                 raise apparmor.AppArmorException(cmd_info[1])
 
     def cmd_audit(self):
+        apparmor.read_profiles()
+
         for (program, profile) in self.get_next_to_profile():
 
-            apparmor.read_profiles()
             output_name = profile if program is None else program
 
             if not os.path.isfile(profile) or 
apparmor.is_skippable_file(profile):
@@ -207,13 +210,13 @@
                 raise apparmor.AppArmorException(cmd_info[1])
 
     def cmd_autodep(self):
+        apparmor.read_profiles()
+
         for (program, profile) in self.get_next_to_profile():
             if not program:
                 aaui.UI_Info(_('Please pass an application to generate a 
profile for, not a profile itself - skipping %s.') % profile)
                 continue
 
-            apparmor.read_profiles()
-
             apparmor.check_qualifiers(program)
 
             if os.path.exists(apparmor.get_profile_filename(program)) and not 
self.force:



Regards,

Christian Boltz

[1] proof-of-concept patch - fixes the problem, but I'm not sure if I 
    want it as final solution (opinions?)

=== modified file 'utils/apparmor/aa.py'
--- utils/apparmor/aa.py        2015-02-20 20:36:55 +0000
+++ utils/apparmor/aa.py        2015-02-20 22:48:43 +0000
@@ -2593,7 +2593,15 @@
             else:
                 read_profile(profile_dir + '/' + file, True)
 
+inactive_profiles_already_read = False
+
 def read_inactive_profiles():
+    global inactive_profiles_already_read
+    if inactive_profiles_already_read:
+        print("read_inactive_profiles called a second time, IGNORING")
+        return
+    inactive_profiles_already_read = True
+
     if not os.path.exists(extra_profile_dir):
         return None
     try:


-- 
> welche log willst sehen ???
Das ist die Postfixbuch-Users Liste, vielleicht das Log von,
hmmm, Postfix? Nur so ne Idee.
[> R. Wilhelm und Ralf Hildebrandt in postfixbuch-users]


-- 
AppArmor mailing list
AppArmor@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor

Reply via email to