[apparmor] [patch] [13/38] Add ANY_EXEC to FileRule
Christian Boltz
apparmor at cboltz.de
Fri Aug 12 20:54:09 UTC 2016
Hello,
aa-logprof needs to check if an exec rule for a given path exists.
This patch adds a __FileAnyExec class to FileRule, as well as ANY_EXEC
(which should be used externally, similar to ALL), and adjusts several
checks to allow it as a special execute mode.
This will allow to use is_covered() (or aa.py is_known_rule()) to find
out if execute is permitted, which replaces aa.py profile_known_exec()
in one of the following patches.
As usual, also add some tests.
[ 13-FileRule-add-ANY_EXEC.diff ]
=== modified file ./utils/apparmor/rule/file.py
--- utils/apparmor/rule/file.py 2016-02-21 15:43:58.009985520 +0100
+++ utils/apparmor/rule/file.py 2016-02-21 16:05:39.673508607 +0100
@@ -35,8 +35,11 @@
# should reference the class field FileRule.ALL
class __FileAll(object):
pass
+ class __FileAnyExec(object):
+ pass
ALL = __FileAll
+ ANY_EXEC = __FileAnyExec
rule_name = 'file'
@@ -76,6 +79,8 @@
if exec_perms is None:
self.exec_perms = None
+ elif exec_perms == self.ANY_EXEC:
+ self.exec_perms = exec_perms
elif type_is_str(exec_perms):
if deny:
if exec_perms != 'x':
@@ -211,6 +216,8 @@
if perm in self.perms:
perm_string = perm_string + perm
+ if self.exec_perms == self.ANY_EXEC:
+ raise AppArmorBug("FileRule.ANY_EXEC can't be used for actual rules")
if self.exec_perms:
perm_string = perm_string + self.exec_perms
@@ -235,12 +242,14 @@
return False
# TODO: handle fallback modes?
- if other_rule.exec_perms and self.exec_perms != other_rule.exec_perms:
+ if other_rule.exec_perms == self.ANY_EXEC and self.exec_perms:
+ pass # avoid hitting the 'elif' branch
+ elif other_rule.exec_perms and self.exec_perms != other_rule.exec_perms:
return False
- # check exec_mode and target only if other_rule contains exec_perms or link permissions
+ # check exec_mode and target only if other_rule contains exec_perms (except ANY_EXEC) or link permissions
# (for mrwk permissions, the target is ignored anyway)
- if other_rule.exec_perms or (other_rule.perms and 'l' in other_rule.perms):
+ if (other_rule.exec_perms and other_rule.exec_perms != self.ANY_EXEC) or (other_rule.perms and 'l' in other_rule.perms):
if not self._is_covered_aare(self.target, self.all_targets, other_rule.target, other_rule.all_targets, 'target'):
return False
=== modified file ./utils/test/test-file.py
--- utils/test/test-file.py 2016-02-21 15:43:58.009985520 +0100
+++ utils/test/test-file.py 2016-02-21 16:05:39.673508607 +0100
@@ -379,6 +379,10 @@
self.assertEqual(expected, obj.get_clean(2), 'unexpected clean rule')
self.assertEqual(expected, obj.get_raw(2), 'unexpected raw rule')
+ def test_write_any_exec(self):
+ obj = FileRule( '/foo', 'rw', FileRule.ANY_EXEC,'/bar', False, False, False)
+ with self.assertRaises(AppArmorBug):
+ obj.get_clean()
class FileCoveredTest(AATest):
def _run_test(self, param, expected):@@ -603,8 +652,6 @@
@@ -584,6 +584,55 @@
self.assertTrue(self.obj.is_equal(self.testobj, strict=False))
self.assertFalse(self.obj.is_equal(self.testobj, strict=True))
+ def test_covered_anyperm_1(self):
+ self.obj = FileRule( '/foo', 'rw', None, '/bar', False, False, False)
+ self.testobj = FileRule( '/foo', 'rw', FileRule.ANY_EXEC, '/bar', False, False, False)
+ self.assertFalse(self.obj.is_covered(self.testobj))
+ self.assertFalse(self.obj.is_equal(self.testobj, strict=False))
+ self.assertFalse(self.obj.is_equal(self.testobj, strict=True))
+
+ def test_covered_anyperm_2(self):
+ self.testobj = FileRule( '/foo', 'rw', FileRule.ANY_EXEC,'/bar', False, False, False)
+ self.assertTrue(self.obj.is_covered(self.testobj))
+ self.assertFalse(self.obj.is_equal(self.testobj, strict=False))
+ self.assertFalse(self.obj.is_equal(self.testobj, strict=True))
+
+ def test_covered_anyperm_3(self):
+ # make sure a different exec target gets ignored with ANY_EXEC
+ self.testobj = FileRule( '/foo', 'rw', FileRule.ANY_EXEC, '/xyz', False, False, False)
+ self.assertTrue(self.obj.is_covered(self.testobj))
+ self.assertFalse(self.obj.is_equal(self.testobj, strict=False))
+ self.assertFalse(self.obj.is_equal(self.testobj, strict=True))
+
+ def test_covered_anyperm_4(self):
+ # make sure a different exec target gets ignored with ANY_EXEC
+ self.testobj = FileRule( '/foo', 'rw', FileRule.ANY_EXEC, FileRule.ALL, False, False, False)
+ self.assertTrue(self.obj.is_covered(self.testobj))
+ self.assertFalse(self.obj.is_equal(self.testobj, strict=False))
+ self.assertFalse(self.obj.is_equal(self.testobj, strict=True))
+
+ def test_covered_anyperm_5(self):
+ # even with ANY_EXEC, a different link target causes a mismatch
+ self.testobj = FileRule( '/foo', 'rwl', FileRule.ANY_EXEC, '/xyz', False, False, False)
+ self.assertFalse(self.obj.is_covered(self.testobj))
+ self.assertFalse(self.obj.is_equal(self.testobj, strict=False))
+ self.assertFalse(self.obj.is_equal(self.testobj, strict=True))
+
+ def test_covered_anyperm_6(self):
+ # even with ANY_EXEC, a different link target causes a mismatch
+ self.testobj = FileRule( '/foo', 'rwl', FileRule.ANY_EXEC, FileRule.ALL, False, False, False)
+ self.assertFalse(self.obj.is_covered(self.testobj))
+ self.assertFalse(self.obj.is_equal(self.testobj, strict=False))
+ self.assertFalse(self.obj.is_equal(self.testobj, strict=True))
+
+ def test_covered_anyperm_7(self):
+ self.obj = FileRule( '/foo', 'rw', 'x', '/bar', False, False, False, deny=True)
+ self.testobj = FileRule( '/foo', 'rw', FileRule.ANY_EXEC,'/bar', False, False, False)
+ self.assertFalse(self.obj.is_covered(self.testobj))
+ self.assertTrue(self.obj.is_covered(self.testobj, check_allow_deny=False))
+ self.assertFalse(self.obj.is_equal(self.testobj, strict=False))
+ self.assertFalse(self.obj.is_equal(self.testobj, strict=True))
+
def test_borked_obj_is_covered_1(self):
self.testobj.path = ''
Regards,
Christian Boltz
--
> If there is some software side way of knowing that...
In this case special hardware, called hammer will help ;-P
[> Carlos E. R. and Cristian Rodríguez in opensuse-factory]
-------------- 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/20160812/08fc2d4e/attachment.pgp>
More information about the AppArmor
mailing list