[apparmor] [patch] Change log_dict to use profile_storage() and simplify log translation

Christian Boltz apparmor at cboltz.de
Fri Dec 25 15:27:10 UTC 2015


Hello,

this patch changes log_dict to use profile_storage() and simplifies the
log translation.

a) change log_dict to profile_storage()

Change collapse_log() to initialize log_dict[aamode][profile][storage]
as profile_storage() instead of a hasher().

This also means path events need to go into
    log_dict[aamode][profile][hat]['allow']['path']
instead of
    log_dict[aamode][profile][hat]['path']
to match the profile_storage() layout.


b) Simplify log translation

The translation from logparser.py's output to *Rule events was more ugly
than needed. This patch removes one step.

Instead of translating log_dict to log_obj in ask_the_questions(), add
*Rule objects to log_dict and adjust ask_the_questions() to use log_dict
instead of log_obj.

This also means log_obj in ask_the_questions() is now superfluous and
can be removed.


c) Other small changes:

- use is_known_rule() instead of .is_covered() for capability events,
  which means included files are also checked now.

- remove the "if rule_obj.log_event != aamode:" check, because
  a) it depends on the content of *Rule.log_event (which means it
     ignores events with log_event != 'ALLOWING' or 'REJECTING'
  b) it's superfluous because the whole code section is wrapped in a
     "for aamode in sorted(log.dict.keys())" which means we have
     separate loops for enforce and complain mode already


Note: I'd have preferred to have separate patches for a) and b), but
both changes depend on each other (and applying only a) breaks 
aa-logprof), therefore I'm submitting everything as one patch.



[ 45-change-log_dict-to-profile_storage.diff ]

=== modified file ./utils/apparmor/aa.py
--- utils/apparmor/aa.py        2015-12-25 15:10:26.931746576 +0100
+++ utils/apparmor/aa.py        2015-12-25 15:12:17.323014813 +0100
@@ -1646,7 +1646,6 @@
 def ask_the_questions():
     found = 0
     global seen_events
-    log_obj = hasher()
     for aamode in sorted(log_dict.keys()):
         # Describe the type of changes
         if aamode == 'PERMITTING':
@@ -1670,35 +1669,9 @@
                 hats = [profile] + hats
 
             for hat in hats:
-                log_obj[profile][hat] = profile_storage(profile, hat, 'ask_the_questions()')
-
-                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)
-
-                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)
-                        log_obj[profile][hat]['network'].add(network_obj)
-
-
-                for peer in sorted(log_dict[aamode][profile][hat]['ptrace'].keys()):
-                    for access in sorted(log_dict[aamode][profile][hat]['ptrace'][peer].keys()):
-                        ptrace_obj = PtraceRule(access, peer, log_event=aamode)
-                        log_obj[profile][hat]['ptrace'].add(ptrace_obj)
-
-                for peer in sorted(log_dict[aamode][profile][hat]['signal'].keys()):
-                    for access in sorted(log_dict[aamode][profile][hat]['signal'][peer].keys()):
-                        for signal in sorted(log_dict[aamode][profile][hat]['signal'][peer][access].keys()):
-                            signal_obj = SignalRule(access, signal, peer, log_event=aamode)
-                            log_obj[profile][hat]['signal'].add(signal_obj)
-
                 for ruletype in ruletypes:
-                    # XXX aa-mergeprof also has this code - if you change it, keep aa-mergeprof in sync!
-                    for rule_obj in log_obj[profile][hat][ruletype].rules:
-
-                        if rule_obj.log_event != aamode:  # XXX does it really make sense to handle enforce and complain mode changes in different rounds?
-                            continue
+                    for rule_obj in log_dict[aamode][profile][hat][ruletype].rules:
+                        # XXX aa-mergeprof also has this code - if you change it, keep aa-mergeprof in sync!
 
                         if is_known_rule(aa[profile][hat], ruletype, rule_obj):
                             continue
@@ -1789,8 +1762,8 @@
                     # END of code (mostly) shared with aa-mergeprof
 
                 # Process all the path entries.
-                for path in sorted(log_dict[aamode][profile][hat]['path'].keys()):
-                    mode = log_dict[aamode][profile][hat]['path'][path]
+                for path in sorted(log_dict[aamode][profile][hat]['allow']['path'].keys()):
+                    mode = log_dict[aamode][profile][hat]['allow']['path'][path]
                     # Lookup modes from profile
                     allow_mode = set()
                     allow_audit = set()
@@ -2490,6 +2463,8 @@
         for profile in prelog[aamode].keys():
             for hat in prelog[aamode][profile].keys():
 
+                log_dict[aamode][profile][hat] = profile_storage(profile, hat, 'collapse_log()')
+
                 for path in prelog[aamode][profile][hat]['path'].keys():
                     mode = prelog[aamode][profile][hat]['path'][path]
 
@@ -2506,35 +2481,37 @@
                     combinedmode |= match_prof_incs_to_path(aa[profile][hat], 'allow', path)[0]
 
                     if not combinedmode or not mode_contains(combinedmode, mode):
-                        if log_dict[aamode][profile][hat]['path'].get(path, False):
-                            mode |= log_dict[aamode][profile][hat]['path'][path]
+                        if log_dict[aamode][profile][hat]['allow']['path'].get(path, False):
+                            mode |= log_dict[aamode][profile][hat]['allow']['path'][path]
 
-                        log_dict[aamode][profile][hat]['path'][path] = mode
+                        log_dict[aamode][profile][hat]['allow']['path'][path] = mode
 
                 for cap in prelog[aamode][profile][hat]['capability'].keys():
-                    # If capability not already in profile
-                    # XXX remove first check when we have proper profile initialisation
-                    if aa[profile][hat].get('capability', False) and not aa[profile][hat]['capability'].is_covered(CapabilityRule(cap, log_event=True)):
-                        log_dict[aamode][profile][hat]['capability'][cap] = True
+                    cap_event = CapabilityRule(cap, log_event=True)
+                    if not is_known_rule(aa[profile][hat], 'capability', cap_event):
+                        log_dict[aamode][profile][hat]['capability'].add(cap_event)
 
                 nd = prelog[aamode][profile][hat]['netdomain']
                 for family in nd.keys():
                     for sock_type in nd[family].keys():
-                        if not is_known_rule(aa[profile][hat], 'network', NetworkRule(family, sock_type, log_event=True)):
-                            log_dict[aamode][profile][hat]['netdomain'][family][sock_type] = True
+                        net_event = NetworkRule(family, sock_type, log_event=True)
+                        if not is_known_rule(aa[profile][hat], 'network', net_event):
+                            log_dict[aamode][profile][hat]['network'].add(net_event)
 
                 ptrace = prelog[aamode][profile][hat]['ptrace']
                 for peer in ptrace.keys():
                     for access in ptrace[peer].keys():
-                        if not is_known_rule(aa[profile][hat], 'ptrace', PtraceRule(access, peer, log_event=True)):
-                            log_dict[aamode][profile][hat]['ptrace'][peer][access] = True
+                        ptrace_event = PtraceRule(access, peer, log_event=True)
+                        if not is_known_rule(aa[profile][hat], 'ptrace', ptrace_event):
+                            log_dict[aamode][profile][hat]['ptrace'].add(ptrace_event)
 
                 sig = prelog[aamode][profile][hat]['signal']
                 for peer in sig.keys():
                     for access in sig[peer].keys():
                         for signal in sig[peer][access].keys():
-                            if not is_known_rule(aa[profile][hat], 'signal', SignalRule(access, signal, peer, log_event=True)):
-                                log_dict[aamode][profile][hat]['signal'][peer][access][signal] = True
+                            signal_event = SignalRule(access, signal, peer, log_event=True)
+                            if not is_known_rule(aa[profile][hat], 'signal', signal_event):
+                                log_dict[aamode][profile][hat]['signal'].add(signal_event)
 
 
 PROFILE_MODE_RE      = re.compile('^(r|w|l|m|k|a|ix|ux|px|pux|cx|pix|cix|cux|Ux|Px|PUx|Cx|Pix|Cix|CUx)+$')



Regards,

Christian Boltz
-- 
Nicht nur Schoenheit, sondern auch Schweinkram liegt ausschliesslich
im Auge des Betrachters.
[Kristian Koehntopp zur Aussage "frauen sind gut zu voegeln" in
http://groups.google.com/groups?selm=3ejajb$ekj@picard.toppoint.de]
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part.
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20151225/c009f540/attachment.pgp>


More information about the AppArmor mailing list