[apparmor] [patch] Add profile_storage()

Christian Boltz apparmor at cboltz.de
Sun Jun 7 13:57:04 UTC 2015


Hello,

profile_storage() returns an empty, properly initialized profile.
It doesn't explicitely init all keys (yet) and will be extended over
time, with the final goal to get rid of hasher().

Also change various places in aa.py to use it (instead of an empty
hasher or sub-hasher), and remove various "init rule class (if not done
yet)" cases.

This also avoids a crash in aa-cleanprof remove_duplicate_rules().
Hats weren't properly initialized in aa.py parse_profile_data()
(especially rule classes were missing), which caused a crash because
hasher doesn't support the delete_duplicates() method.



[ 48-add-profile_storage.diff ]

=== modified file utils/apparmor/aa.py
--- utils/apparmor/aa.py        2015-06-07 14:49:41.432239728 +0200
+++ utils/apparmor/aa.py        2015-06-07 15:50:58.057162382 +0200
@@ -104,12 +104,6 @@
 t = hasher()  # dict()
 transitions = hasher()
 
-# keys used in aa[profile][hat]:
-# a) rules (as dict): alias, include, lvar
-# b) rules (as hasher): allow, deny
-# c) one for each rule class
-# d) other: external, flags, name, profile, attachment, initial_comment,
-#           profile_keyword, header_comment (these two are currently only set by set_profile_flags())
 aa = hasher()  # Profiles originally in sd, replace by aa
 original_aa = hasher()
 extras = hasher()  # Inactive profiles from extras
@@ -408,8 +402,35 @@
         return {local_profile: extras[local_profile]}
     return dict()
 
+def profile_storage():
+    # keys used in aa[profile][hat]:
+    # a) rules (as dict): alias, include, lvar
+    # b) rules (as hasher): allow, deny
+    # c) one for each rule class
+    # d) other: external, flags, name, profile, attachment, initial_comment,
+    #           profile_keyword, header_comment (these two are currently only set by set_profile_flags())
+
+    # Note that this function doesn't explicitely init all those keys (yet).
+    # It will be extended over time, with the final goal to get rid of hasher().
+
+    profile = hasher()
+
+    profile['capability']       = CapabilityRuleset()
+    profile['change_profile']   = ChangeProfileRuleset()
+    profile['network']          = NetworkRuleset()
+    profile['rlimit']           = RlimitRuleset()
+
+    profile['allow']['path'] = hasher()
+    profile['allow']['dbus'] = list()
+    profile['allow']['mount'] = list()
+    profile['allow']['signal'] = list()
+    profile['allow']['ptrace'] = list()
+    profile['allow']['pivot_root'] = list()
+
+    return profile
+
 def create_new_profile(localfile, is_stub=False):
-    local_profile = hasher()
+    local_profile = profile_storage()
     local_profile[localfile]['flags'] = 'complain'
     local_profile[localfile]['include']['abstractions/base'] = 1
 
@@ -1442,6 +1463,7 @@
                                 ynans = aaui.UI_YesNo(_('A profile for %s does not exist.\nDo you want to create one?') % exec_target, 'n')
                             if ynans == 'y':
                                 hat = exec_target
+                                # XXX do we need to init the profile here?
                                 aa[profile][hat]['profile'] = True
 
                                 if profile != hat:
@@ -1566,16 +1588,12 @@
                 hats = [profile] + hats
 
             for hat in hats:
-                if not log_obj[profile][hat].get('capability', False):
-                    log_obj[profile][hat]['capability'] = CapabilityRuleset()
+                log_obj[profile][hat] = profile_storage()
 
                 for capability in sorted(log_dict[aamode][profile][hat]['capability'].keys()):
                     capability_obj = CapabilityRule(capability, log_event=aamode)
                     log_obj[profile][hat]['capability'].add(capability_obj)
 
-                if not log_obj[profile][hat].get('network', False):
-                    log_obj[profile][hat]['network'] = NetworkRuleset()
-
                 for family in sorted(log_dict[aamode][profile][hat]['netdomain'].keys()):
                     for sock_type in sorted(log_dict[aamode][profile][hat]['netdomain'][family].keys()):
                         network_obj = NetworkRule(family, sock_type, log_event=aamode)
@@ -2562,6 +2580,8 @@
     if do_include:
         profile = file
         hat = file
+        profile_data[profile][hat] = profile_storage()
+
     for lineno, line in enumerate(data):
         line = line.strip()
         if not line:
@@ -2578,6 +2598,8 @@
                 raise AppArmorException('Profile %(profile)s defined twice in %(file)s, last found in line %(line)s' %
                     { 'file': file, 'line': lineno + 1, 'profile': combine_name(profile, hat) })
 
+            profile_data[profile][hat] = profile_storage()
+
             if attachment:
                 profile_data[profile][hat]['attachment'] = attachment
             if pps_set_profile:
@@ -2595,15 +2617,6 @@
 
             profile_data[profile][hat]['flags'] = flags
 
-            profile_data[profile][hat]['network'] = NetworkRuleset()
-            profile_data[profile][hat]['change_profile'] = ChangeProfileRuleset()
-            profile_data[profile][hat]['rlimit'] = RlimitRuleset()
-            profile_data[profile][hat]['allow']['path'] = hasher()
-            profile_data[profile][hat]['allow']['dbus'] = list()
-            profile_data[profile][hat]['allow']['mount'] = list()
-            profile_data[profile][hat]['allow']['signal'] = list()
-            profile_data[profile][hat]['allow']['ptrace'] = list()
-            profile_data[profile][hat]['allow']['pivot_root'] = list()
             # Save the initial comment
             if initial_comment:
                 profile_data[profile][hat]['initial_comment'] = initial_comment
@@ -2614,10 +2627,6 @@
                 profile_data[profile][profile]['repo']['url'] = repo_data['url']
                 profile_data[profile][profile]['repo']['user'] = repo_data['user']
 
-            # init rule classes (if not done yet)
-            if not profile_data[profile][hat].get('capability', False):
-                profile_data[profile][hat]['capability'] = CapabilityRuleset()
-
         elif RE_PROFILE_END.search(line):
             # If profile ends and we're not in one
             if not profile:
@@ -2636,10 +2645,6 @@
             if not profile:
                 raise AppArmorException(_('Syntax Error: Unexpected capability entry found in file: %(file)s line: %(line)s') % { 'file': file, 'line': lineno + 1 })
 
-            # init rule class (if not done yet)
-            if not profile_data[profile][hat].get('capability', False):
-                profile_data[profile][hat]['capability'] = CapabilityRuleset()
-
             profile_data[profile][hat]['capability'].add(CapabilityRule.parse(line))
 
         elif RE_PROFILE_LINK.search(line):
@@ -2693,10 +2698,6 @@
             if not profile:
                 raise AppArmorException(_('Syntax Error: Unexpected rlimit entry found in file: %(file)s line: %(line)s') % { 'file': file, 'line': lineno + 1 })
 
-            # init rule class (if not done yet)
-            if not profile_data[profile][hat].get('rlimit', False):
-                profile_data[profile][hat]['rlimit'] = RlimitRuleset()
-
             profile_data[profile][hat]['rlimit'].add(RlimitRule.parse(line))
 
         elif RE_PROFILE_BOOLEAN.search(line):
@@ -3003,11 +3004,15 @@
             in_contained_hat = True
             hat = matches.group('hat')
             hat = strip_quotes(hat)
+
+            # if hat is already known, the filelist check some lines below will error out.
+            # nevertheless, just to be sure, don't overwrite existing profile_data.
+            if not profile_data[profile].get(hat, False):
+                profile_data[profile][hat] = profile_storage()
+
             flags = matches.group('flags')
 
             profile_data[profile][hat]['flags'] = flags
-            #profile_data[profile][hat]['allow']['path'] = hasher()
-            #profile_data[profile][hat]['allow']['netdomain'] = hasher()
 
             if initial_comment:
                 profile_data[profile][hat]['initial_comment'] = initial_comment


Regards,

Christian Boltz
-- 
> I see no "do" in your script, so this will give you a "syntax error
> near unexpected token `done'" after shutdown ;-))
I've been hearing funny noises after shutdown, that must be it :-)
[> Christian Boltz and Chris Maaskant in opensuse]




More information about the AppArmor mailing list