[apparmor] [patch] logparser.py: improve file vs. network event recognition
Christian Boltz
apparmor at cboltz.de
Sun Nov 20 15:52:46 UTC 2016
Hello,
sometimes network events come with an operation keyword looking like
file_perm which makes them look like file events. Instead of ignoring
these events (which was a hotfix to avoid crashes), improve the type
detection.
In detail, this means:
- replace OPERATION_TYPES (which was basically a list of network event
keywords) with OP_TYPE_FILE_OR_NET (which is a list of keywords for
file and network events)
- change op_type() parameters to expect the whole event, not only the
operation keyword, and rebuild the type detection based on the event
details
- as a side effect, this simplifies the detection for file event
operations in parse_event_for_tree()
- remove workaround code from parse_event_for_tree()
Also add 4 new testcases with log messages that were ignored before.
References:
a) various bugreports about crashes caused by unexpected operation keywords:
https://bugs.launchpad.net/apparmor/+bug/1466812
https://bugs.launchpad.net/apparmor/+bug/1509030
https://bugs.launchpad.net/apparmor/+bug/1540562
https://bugs.launchpad.net/apparmor/+bug/1577051
https://bugs.launchpad.net/apparmor/+bug/1582374
b) the summary bug for this patch
https://bugs.launchpad.net/apparmor/+bug/1613061
(that will make quite some --fixes for bzr commit ;-)
I propose this patch for trunk and 2.10.
[ 02-logparser-improve-file-vs-net.diff ]
--- utils/apparmor/logparser.py 2016-11-20 16:00:37.374243431 +0100
+++ utils/apparmor/logparser.py 2016-11-20 16:01:19.158060468 +0100
@@ -1,6 +1,6 @@
# ----------------------------------------------------------------------
# Copyright (C) 2013 Kshitij Gupta <kgupta8592 at gmail.com>
-# Copyright (C) 2015 Christian Boltz <apparmor at cboltz.de>
+# Copyright (C) 2015-2016 Christian Boltz <apparmor at cboltz.de>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
@@ -43,25 +43,6 @@
# used to pre-filter log lines so that we hand over only relevant lines to LibAppArmor parsing
RE_LOG_ALL = re.compile('(' + '|'.join(RE_log_parts) + ')')
-
- # Used by netdomain to identify the operation types
- # New socket names
- OPERATION_TYPES = {'create': 'net',
- 'post_create': 'net',
- 'bind': 'net',
- 'connect': 'net',
- 'listen': 'net',
- 'accept': 'net',
- 'sendmsg': 'net',
- 'recvmsg': 'net',
- 'getsockname': 'net',
- 'getpeername': 'net',
- 'getsockopt': 'net',
- 'setsockopt': 'net',
- 'socket_create': 'net',
- 'sock_shutdown': 'net'
- }
-
def __init__(self, pid, filename, existing_profiles, profile_dir, log):
self.filename = filename
self.profile_dir = profile_dir
@@ -295,25 +276,7 @@
else:
self.debug_logger.debug('parse_event_for_tree: dropped exec event in %s' % e['profile'])
- elif ( e['operation'].startswith('file_') or e['operation'].startswith('inode_') or
- e['operation'] in ['open', 'truncate', 'mkdir', 'mknod', 'chmod', 'chown', 'rename_src',
- 'rename_dest', 'unlink', 'rmdir', 'symlink_create', 'link',
- 'sysctl', 'getattr', 'setattr', 'xattr'] ):
-
- # for some kernel-side reason, we get file-related log events without request_mask, see
- # https://bugs.launchpad.net/apparmor/+bug/1466812/, https://bugs.launchpad.net/apparmor/+bug/1509030 and https://bugs.launchpad.net/apparmor/+bug/1540562
- # request_mask can also be '', see https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/1525119
- if not e['request_mask']:
- self.debug_logger.debug('UNHANDLED (missing request_mask): %s' % e)
- return None
-
- # sometimes network events come with an e['operation'] that matches the list of file operations
- # see https://bugs.launchpad.net/apparmor/+bug/1577051 and https://bugs.launchpad.net/apparmor/+bug/1582374
- # XXX these events are network events, so we should map them as such
- if 'send' in e['request_mask'] or 'receive' in e['request_mask']:
- self.debug_logger.debug('UNHANDLED (request_mask is send or receive): %s' % e)
- return None
-
+ elif self.op_type(e) == 'file':
# Map c (create) and d (delete) to w (logging is more detailed than the profile language)
rmask = e['request_mask']
rmask = rmask.replace('c', 'w')
@@ -373,7 +336,7 @@
# self.log += [arrayref]
# self.pid[child] = arrayref
- elif self.op_type(e['operation']) == 'net':
+ elif self.op_type(e) == 'net':
return(e['pid'], e['parent'], 'netdomain',
[profile, hat, prog, aamode, e['family'], e['sock_type'], e['protocol']])
elif e['operation'] == 'change_hat':
@@ -433,10 +396,57 @@
self.logmark = ''
return self.log
+ # operation types that can be network or file operations
+ # (used by op_type() which checks some event details to decide)
+ OP_TYPE_FILE_OR_NET = {
+ # Note: op_type() also uses some startswith() checks which are not listed here!
+ 'create',
+ 'post_create',
+ 'bind',
+ 'connect',
+ 'listen',
+ 'accept',
+ 'sendmsg',
+ 'recvmsg',
+ 'getsockname',
+ 'getpeername',
+ 'getsockopt',
+ 'setsockopt',
+ 'socket_create',
+ 'sock_shutdown',
+ 'open',
+ 'truncate',
+ 'mkdir',
+ 'mknod',
+ 'chmod',
+ 'chown',
+ 'rename_src',
+ 'rename_dest',
+ 'unlink',
+ 'rmdir',
+ 'symlink_create',
+ 'link',
+ 'sysctl',
+ 'getattr',
+ 'setattr',
+ 'xattr',
+ }
+
- def op_type(self, operation):
+ def op_type(self, event):
"""Returns the operation type if known, unkown otherwise"""
- operation_type = self.OPERATION_TYPES.get(operation, 'unknown')
- return operation_type
+
+ if ( event['operation'].startswith('file_') or event['operation'].startswith('inode_') or event['operation'] in self.OP_TYPE_FILE_OR_NET ):
+ # file or network event?
+ if event['family'] and event['protocol'] and event['sock_type']:
+ # 'unix' events also use keywords like 'connect', but protocol is 0 and should therefore be filtered out
+ return 'net'
+ elif event['denied_mask']:
+ return 'file'
+ else:
+ raise AppArmorException('unknown file or network event type')
+
+ else:
+ return 'unknown'
def profile_exists(self, program):
"""Returns True if profile exists, False otherwise"""
=== added file 'libraries/libapparmor/testsuite/test_multi/file_inherit_network_lp1509030.err'
=== added file 'libraries/libapparmor/testsuite/test_multi/file_inherit_network_lp1509030.in'
--- libraries/libapparmor/testsuite/test_multi/file_inherit_network_lp1509030.in 1970-01-01 00:00:00 +0000
+++ libraries/libapparmor/testsuite/test_multi/file_inherit_network_lp1509030.in 2016-11-20 15:28:09 +0000
@@ -0,0 +1,1 @@
+Oct 22 15:57:38 NR021AA kernel: [ 69.827705] audit: type=1400 audit(1445522258.769:1054): apparmor="DENIED" operation="file_inherit" profile="/usr/lib/NetworkManager/nm-dhcp-client.action" pid=2407 comm="nm-dhcp-client." lport=10580 family="inet6" sock_type="dgram" protocol=17
=== added file 'libraries/libapparmor/testsuite/test_multi/file_inherit_network_lp1509030.out'
--- libraries/libapparmor/testsuite/test_multi/file_inherit_network_lp1509030.out 1970-01-01 00:00:00 +0000
+++ libraries/libapparmor/testsuite/test_multi/file_inherit_network_lp1509030.out 2016-11-20 15:28:44 +0000
@@ -0,0 +1,14 @@
+START
+File: file_inherit_network_lp1509030.in
+Event type: AA_RECORD_DENIED
+Audit ID: 1445522258.769:1054
+Operation: file_inherit
+Profile: /usr/lib/NetworkManager/nm-dhcp-client.action
+Command: nm-dhcp-client.
+PID: 2407
+Network family: inet6
+Socket type: dgram
+Protocol: udp
+Local port: 10580
+Epoch: 1445522258
+Audit subid: 1054
=== added file 'libraries/libapparmor/testsuite/test_multi/file_inherit_network_lp1509030.profile'
--- libraries/libapparmor/testsuite/test_multi/file_inherit_network_lp1509030.profile 1970-01-01 00:00:00 +0000
+++ libraries/libapparmor/testsuite/test_multi/file_inherit_network_lp1509030.profile 2016-11-20 14:47:46 +0000
@@ -0,0 +1,4 @@
+/usr/lib/NetworkManager/nm-dhcp-client.action {
+ network inet6 dgram,
+
+}
=== added file 'libraries/libapparmor/testsuite/test_multi/file_perm_network_lp1466812.err'
=== added file 'libraries/libapparmor/testsuite/test_multi/file_perm_network_lp1466812.in'
--- libraries/libapparmor/testsuite/test_multi/file_perm_network_lp1466812.in 1970-01-01 00:00:00 +0000
+++ libraries/libapparmor/testsuite/test_multi/file_perm_network_lp1466812.in 2015-10-28 20:34:22 +0000
@@ -0,0 +1,1 @@
+Jun 19 12:00:55 piorun kernel: [4475115.459952] audit: type=1400 audit(1434708055.676:19629): apparmor="ALLOWED" operation="file_perm" profile="/usr/sbin/apache2" pid=3512 comm="apache2" laddr=::ffff:192.168.236.159 lport=80 faddr=::ffff:192.168.103.80 fport=61985 family="inet6" sock_type="stream" protocol=6
=== added file 'libraries/libapparmor/testsuite/test_multi/file_perm_network_lp1466812.out'
--- libraries/libapparmor/testsuite/test_multi/file_perm_network_lp1466812.out 1970-01-01 00:00:00 +0000
+++ libraries/libapparmor/testsuite/test_multi/file_perm_network_lp1466812.out 2016-11-20 15:32:21 +0000
@@ -0,0 +1,17 @@
+START
+File: file_perm_network_lp1466812.in
+Event type: AA_RECORD_ALLOWED
+Audit ID: 1434708055.676:19629
+Operation: file_perm
+Profile: /usr/sbin/apache2
+Command: apache2
+PID: 3512
+Network family: inet6
+Socket type: stream
+Protocol: tcp
+Local addr: ::ffff:192.168.236.159
+Foreign addr: ::ffff:192.168.103.80
+Local port: 80
+Foreign port: 61985
+Epoch: 1434708055
+Audit subid: 19629
=== added file 'libraries/libapparmor/testsuite/test_multi/file_perm_network_lp1466812.profile'
--- libraries/libapparmor/testsuite/test_multi/file_perm_network_lp1466812.profile 1970-01-01 00:00:00 +0000
+++ libraries/libapparmor/testsuite/test_multi/file_perm_network_lp1466812.profile 2016-11-18 21:10:38 +0000
@@ -0,0 +1,4 @@
+/usr/sbin/apache2 {
+ network inet6 stream,
+
+}
=== added file 'libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1577051.err'
=== added file 'libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1577051.in'
--- libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1577051.in 1970-01-01 00:00:00 +0000
+++ libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1577051.in 2016-11-20 14:37:50 +0000
@@ -0,0 +1,1 @@
+type=AVC msg=audit(1463403689.381:267599): apparmor="ALLOWED" operation="file_perm" profile="/usr/sbin/apache2//www.xxxxxxxxxx.co.uk" pid=13215 comm="apache2" laddr=::ffff:192.168.1.100 lport=80 faddr=::ffff:192.168.1.100 fport=45658 family="inet6" sock_type="stream" protocol=6 requested_mask="send" denied_mask="send"
=== added file 'libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1577051.out'
--- libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1577051.out 1970-01-01 00:00:00 +0000
+++ libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1577051.out 2016-11-20 15:32:08 +0000
@@ -0,0 +1,19 @@
+START
+File: file_perm_network_receive_lp1577051.in
+Event type: AA_RECORD_ALLOWED
+Audit ID: 1463403689.381:267599
+Operation: file_perm
+Mask: send
+Denied Mask: send
+Profile: /usr/sbin/apache2//www.xxxxxxxxxx.co.uk
+Command: apache2
+PID: 13215
+Network family: inet6
+Socket type: stream
+Protocol: tcp
+Local addr: ::ffff:192.168.1.100
+Foreign addr: ::ffff:192.168.1.100
+Local port: 80
+Foreign port: 45658
+Epoch: 1463403689
+Audit subid: 267599
=== added file 'libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1577051.profile'
--- libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1577051.profile 1970-01-01 00:00:00 +0000
+++ libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1577051.profile 2016-11-20 14:38:05 +0000
@@ -0,0 +1,7 @@
+/usr/sbin/apache2 {
+
+ ^www.xxxxxxxxxx.co.uk {
+ network inet6 stream,
+
+ }
+}
=== added file 'libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1582374.err'
=== added file 'libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1582374.in'
--- libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1582374.in 1970-01-01 00:00:00 +0000
+++ libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1582374.in 2016-05-20 22:34:29 +0000
@@ -0,0 +1,1 @@
+Apr 30 21:53:05 nova kernel: [24668.960760] audit: type=1400 audit(1462045985.636:2154): apparmor="ALLOWED" operation="file_perm" profile="/usr/local/apache-tomcat-8.0.33/bin/catalina.sh///usr/local/jdk1.8.0_92/bin/java" pid=12529 comm="java" laddr=::ffff:127.0.0.1 lport=8080 faddr=::ffff:127.0.0.1 fport=52308 family="inet6" sock_type="stream" protocol=6 requested_mask="receive" denied_mask="receive"
=== added file 'libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1582374.out'
--- libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1582374.out 1970-01-01 00:00:00 +0000
+++ libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1582374.out 2016-11-20 15:31:55 +0000
@@ -0,0 +1,19 @@
+START
+File: file_perm_network_receive_lp1582374.in
+Event type: AA_RECORD_ALLOWED
+Audit ID: 1462045985.636:2154
+Operation: file_perm
+Mask: receive
+Denied Mask: receive
+Profile: /usr/local/apache-tomcat-8.0.33/bin/catalina.sh///usr/local/jdk1.8.0_92/bin/java
+Command: java
+PID: 12529
+Network family: inet6
+Socket type: stream
+Protocol: tcp
+Local addr: ::ffff:127.0.0.1
+Foreign addr: ::ffff:127.0.0.1
+Local port: 8080
+Foreign port: 52308
+Epoch: 1462045985
+Audit subid: 2154
=== added file 'libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1582374.profile'
--- libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1582374.profile 1970-01-01 00:00:00 +0000
+++ libraries/libapparmor/testsuite/test_multi/file_perm_network_receive_lp1582374.profile 2016-11-18 21:12:57 +0000
@@ -0,0 +1,7 @@
+/usr/local/apache-tomcat-8.0.33/bin/catalina.sh {
+
+ ^/usr/local/jdk1.8.0_92/bin/java {
+ network inet6 stream,
+
+ }
+}
Regards,
Christian Boltz
--
Wenn man keine Vögel mag, ist es völlig in Ordnung, mit Kanonen auf
Spatzen zu schiessen. [Ratti in suse-linux]
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: This is a digitally signed message part.
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20161120/f9a50b48/attachment-0001.pgp>
More information about the AppArmor
mailing list