Add support for ptrace log events to aa-logprof

In detail, this means:
- handle ptrace events in logparser.py
- "translate" those events in aa.py - from log (logparser.py readlog())
  to prelog (handle_children()) to log_dict (collapse_log()) to
  log_obj (ask_the_questions())
  (yes, really! :-/ - needless to say that this is ugly...)
- finally ask the user about the ptrace in ask_the_questions()

Also add a logparser test to test-ptrace.py to ensure the logparser step
works as expected.

Note that the aa.py changes are not covered by tests, however they
worked in a manual test.


If you want to test manually, try this (faked) log line:
    msg=audit(1409700683.304:547661): apparmor="DENIED" operation="ptrace" profile="/usr/sbin/smbd" pid=22465 comm="ptrace" requested_mask="trace" denied_mask="trace" peer="/foo/bar"


Acked-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
Christian Boltz 2015-12-27 01:22:51 +01:00
parent 813dbef2aa
commit d813ae657d
2 changed files with 24 additions and 0 deletions

View file

@ -1128,6 +1128,16 @@ def handle_children(profile, hat, root):
continue
prelog[aamode][profile][hat]['capability'][capability] = True
elif typ == 'ptrace':
# If ptrace then we (should) have pid, profile, hat, program, mode, access and peer
pid, p, h, prog, aamode, access, peer = entry
if not regex_nullcomplain.search(p) and not regex_nullcomplain.search(h):
profile = p
hat = h
if not profile or not hat:
continue
prelog[aamode][profile][hat]['ptrace'][peer][access] = True
elif typ == 'signal':
# If signal then we (should) have pid, profile, hat, program, mode, access, signal and peer
pid, p, h, prog, aamode, access, signal, peer = entry
@ -1641,6 +1651,11 @@ def ask_the_questions():
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()):
@ -2472,6 +2487,12 @@ def collapse_log():
if not is_known_rule(aa[profile][hat], 'network', NetworkRule(family, sock_type)):
log_dict[aamode][profile][hat]['netdomain'][family][sock_type] = True
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_dict[aamode][profile][hat]['ptrace'][peer][access] = True
sig = prelog[aamode][profile][hat]['signal']
for peer in sig.keys():
for access in sig[peer].keys():

View file

@ -359,6 +359,9 @@ class ReadLog:
elif e['operation'] == 'change_hat':
return(e['pid'], e['parent'], 'unknown_hat',
[profile, hat, aamode, hat])
elif e['operation'] == 'ptrace':
return(e['pid'], e['parent'], 'ptrace',
[profile, hat, prog, aamode, e['denied_mask'], e['peer']])
elif e['operation'] == 'signal':
return(e['pid'], e['parent'], 'signal',
[profile, hat, prog, aamode, e['denied_mask'], e['signal'], e['peer']])