Complete TERuleQuery changes for extended permission rules.

Related to #73.
This commit is contained in:
Chris PeBenito 2016-03-22 11:07:25 -04:00
parent c56e01bc8c
commit a9cd2248e9
4 changed files with 258 additions and 30 deletions

View File

@ -21,6 +21,7 @@ import re
from . import mixins, query
from .descriptors import CriteriaDescriptor, CriteriaSetDescriptor
from .policyrep import ioctlSet
from .policyrep.exception import RuleUseError, RuleNotConditional
@ -92,6 +93,31 @@ class TERuleQuery(mixins.MatchObjClass, mixins.MatchPermission, query.PolicyQuer
boolean = CriteriaSetDescriptor("boolean_regex", "lookup_boolean")
boolean_regex = False
boolean_equal = False
_xperms = None
xperms_equal = False
@property
def xperms(self):
return self._xperms
@xperms.setter
def xperms(self, value):
pending_xperms = ioctlSet()
for low, high in value:
if not (0 <= low <= 0xffff):
raise ValueError("{0:04x} is not a valid ioctl.".format(low))
if not (0 <= high <= 0xffff):
raise ValueError("{0:04x} is not a valid ioctl.".format(high))
if high < low:
raise ValueError("0x{0:04x}-0x{1:04x} is not a valid ioctl range.".
format(low, high))
pending_xperms.update(i for i in range(low, high+1))
self._xperms = pending_xperms
def __init__(self, policy, **kwargs):
super(TERuleQuery, self).__init__(policy, **kwargs)
@ -108,6 +134,7 @@ class TERuleQuery(mixins.MatchObjClass, mixins.MatchPermission, query.PolicyQuer
self.log.debug("Class: {0.tclass!r}, regex: {0.tclass_regex}".format(self))
self.log.debug("Perms: {0.perms!r}, regex: {0.perms_regex}, eq: {0.perms_equal}".
format(self))
self.log.debug("Xperms: {0.xperms!r}, eq: {0.xperms_equal}".format(self))
self.log.debug("Default: {0.default!r}, regex: {0.default_regex}".format(self))
self.log.debug("Boolean: {0.boolean!r}, eq: {0.boolean_equal}, "
"regex: {0.boolean_regex}".format(self))
@ -150,11 +177,34 @@ class TERuleQuery(mixins.MatchObjClass, mixins.MatchPermission, query.PolicyQuer
# Matching on permission set
#
try:
if not self._match_perms(rule):
if self.perms and rule.extended:
if self.perms_equal and len(self.perms) > 1:
# if criteria is more than one standard permission,
# extended perm rules can never match if the
# permission set equality option is on.
continue
if rule.xperm_type not in self.perms:
continue
elif not self._match_perms(rule):
continue
except RuleUseError:
continue
#
# Matching on extended permissions
#
try:
if self.xperms and not self._match_regex_or_set(
rule.perms,
self.xperms,
self.xperms_equal,
False):
continue
except RuleUseError:
continue
#
# Matching on default type
#

View File

@ -27,7 +27,7 @@ class ValidateRule(unittest.TestCase):
"""Mixin for validating policy rules."""
def validate_rule(self, rule, ruletype, source, target, tclass, last_item, cond=None,
cond_block=None):
cond_block=None, xperm=None):
"""Validate a rule."""
self.assertEqual(ruletype, rule.ruletype)
self.assertEqual(source, rule.source)
@ -48,20 +48,9 @@ class ValidateRule(unittest.TestCase):
if cond_block is not None:
self.assertEqual(cond_block, rule.conditional_block)
class ValidateXpermRule(unittest.TestCase):
"""Mixin for validating policy xperm rules."""
def validate_xperm_rule(self, rule, ruletype, source, target, tclass):
"""Validate a rule."""
self.assertEqual(ruletype, rule.ruletype)
self.assertEqual(source, rule.source)
self.assertEqual(target, rule.target)
self.assertEqual(tclass, rule.tclass)
# try:
# # This is the common case.
# self.assertSetEqual(last_item, rule.perms)
# except (AttributeError, RuleUseError):
# self.assertEqual(last_item, rule.default)
if xperm:
self.assertEqual(xperm, rule.xperm_type)
self.assertTrue(rule.extended)
else:
self.assertRaises(AttributeError, getattr, rule, "xperm_type")
self.assertFalse(rule.extended)

View File

@ -282,3 +282,178 @@ class TERuleQueryTest(mixins.ValidateRule, unittest.TestCase):
"test302t1")
self.validate_rule(r[1], "type_transition", "test302source", "test302t2", "infoflow7",
"test302t2")
class TERuleQueryXperm(mixins.ValidateRule, unittest.TestCase):
"""TE Rule Query with extended permission rules."""
@classmethod
def setUpClass(cls):
cls.p = SELinuxPolicy("tests/terulequery2.conf")
def test_001_source_direct(self):
"""Xperm rule query with exact, direct, source match."""
q = TERuleQuery(
self.p, source="test1a", source_indirect=False, source_regex=False)
r = sorted(q.results())
self.assertEqual(len(r), 1)
self.validate_rule(r[0], "allowxperm", "test1a", "test1t", "infoflow",
set(range(0xebe0, 0xebff+1)), xperm="ioctl")
def test_002_source_indirect(self):
"""Xperm rule query with exact, indirect, source match."""
q = TERuleQuery(
self.p, source="test2s", source_indirect=True, source_regex=False)
r = sorted(q.results())
self.assertEqual(len(r), 1)
self.validate_rule(r[0], "allowxperm", "test2a", "test2t", "infoflow",
set([0x5411, 0x5451]), xperm="ioctl")
def test_003_source_direct_regex(self):
"""Xperm rule query with regex, direct, source match."""
q = TERuleQuery(
self.p, source="test3a.*", source_indirect=False, source_regex=True)
r = sorted(q.results())
self.assertEqual(len(r), 1)
self.validate_rule(r[0], "allowxperm", "test3aS", "test3t", "infoflow",
set([0x1111]), xperm="ioctl")
def test_004_source_indirect_regex(self):
"""Xperm rule query with regex, indirect, source match."""
q = TERuleQuery(
self.p, source="test4(s|t)", source_indirect=True, source_regex=True)
r = sorted(q.results())
self.assertEqual(len(r), 2)
self.validate_rule(r[0], "allowxperm", "test4a1", "test4a1", "infoflow",
set([0x9999]), xperm="ioctl")
self.validate_rule(r[1], "allowxperm", "test4a2", "test4a2", "infoflow",
set([0x1111]), xperm="ioctl")
def test_005_target_direct(self):
"""Xperm rule query with exact, direct, target match."""
q = TERuleQuery(
self.p, target="test5a", target_indirect=False, target_regex=False)
r = sorted(q.results())
self.assertEqual(len(r), 1)
self.validate_rule(r[0], "allowxperm", "test5s", "test5a", "infoflow", set([0x9999]),
xperm="ioctl")
def test_006_target_indirect(self):
"""Xperm rule query with exact, indirect, target match."""
q = TERuleQuery(
self.p, target="test6t", target_indirect=True, target_regex=False)
r = sorted(q.results())
self.assertEqual(len(r), 2)
self.validate_rule(r[0], "allowxperm", "test6s", "test6a", "infoflow", set([0x9999]),
xperm="ioctl")
self.validate_rule(r[1], "allowxperm", "test6s", "test6t", "infoflow", set([0x1111]),
xperm="ioctl")
def test_007_target_direct_regex(self):
"""Xperm rule query with regex, direct, target match."""
q = TERuleQuery(
self.p, target="test7a.*", target_indirect=False, target_regex=True)
r = sorted(q.results())
self.assertEqual(len(r), 1)
self.validate_rule(r[0], "allowxperm", "test7s", "test7aPASS", "infoflow", set([0x1111]),
xperm="ioctl")
def test_008_target_indirect_regex(self):
"""Xperm rule query with regex, indirect, target match."""
q = TERuleQuery(
self.p, target="test8(s|t)", target_indirect=True, target_regex=True)
r = sorted(q.results())
self.assertEqual(len(r), 2)
self.validate_rule(r[0], "allowxperm", "test8a1", "test8a1", "infoflow", set([0x9999]),
xperm="ioctl")
self.validate_rule(r[1], "allowxperm", "test8a2", "test8a2", "infoflow", set([0x1111]),
xperm="ioctl")
def test_010_class_list(self):
"""Xperm rule query with object class list match."""
q = TERuleQuery(
self.p, tclass=["infoflow3", "infoflow4"], tclass_regex=False)
r = sorted(q.results())
self.assertEqual(len(r), 2)
self.validate_rule(r[0], "allowxperm", "test10", "test10", "infoflow3", set([0]),
xperm="ioctl")
self.validate_rule(r[1], "allowxperm", "test10", "test10", "infoflow4", set([0x9999]),
xperm="ioctl")
def test_011_class_regex(self):
"""Xperm rule query with object class regex match."""
q = TERuleQuery(self.p, tclass="infoflow(5|6)", tclass_regex=True)
r = sorted(q.results())
self.assertEqual(len(r), 2)
self.validate_rule(r[0], "allowxperm", "test11", "test11", "infoflow5", set([0x1111]),
xperm="ioctl")
self.validate_rule(r[1], "allowxperm", "test11", "test11", "infoflow6", set([0x5555]),
xperm="ioctl")
def test_014_ruletype(self):
"""Xperm rule query with rule type match."""
q = TERuleQuery(self.p, ruletype=["auditallowxperm", "dontauditxperm"])
r = sorted(q.results())
self.assertEqual(len(r), 2)
self.validate_rule(r[0], "auditallowxperm", "test14", "test14", "infoflow7", set([0x1234]),
xperm="ioctl")
self.validate_rule(r[1], "dontauditxperm", "test14", "test14", "infoflow7", set([0x4321]),
xperm="ioctl")
def test_100_std_perm_any(self):
"""Xperm rule query match by standard permission."""
q = TERuleQuery(self.p, ruletype=["neverallow", "neverallowxperm"],
perms=set(["ioctl", "hi_w"]), perms_equal=False)
r = sorted(q.results())
self.assertEqual(len(r), 2)
self.validate_rule(r[0], "neverallow", "test100", "system", "infoflow2",
set(["ioctl", "hi_w"]))
self.validate_rule(r[1], "neverallowxperm", "test100", "test100", "infoflow2",
set([0x1234]), xperm="ioctl")
def test_100_std_perm_equal(self):
"""Xperm rule query match by standard permission, equal perm set."""
q = TERuleQuery(self.p, ruletype=["neverallow", "neverallowxperm"],
perms=set(["ioctl", "hi_w"]), perms_equal=True)
r = sorted(q.results())
self.assertEqual(len(r), 1)
self.validate_rule(r[0], "neverallow", "test100", "system", "infoflow2",
set(["ioctl", "hi_w"]))
def test_101_xperm_any(self):
"""Xperm rule query match any perm set."""
q = TERuleQuery(self.p, xperms=[(0x9011, 0x9013)], xperms_equal=False)
r = sorted(q.results())
self.assertEqual(len(r), 4)
self.validate_rule(r[0], "allowxperm", "test101a", "test101a", "infoflow7",
set([0x9011]), xperm="ioctl")
self.validate_rule(r[1], "allowxperm", "test101b", "test101b", "infoflow7",
set([0x9011, 0x9012]), xperm="ioctl")
self.validate_rule(r[2], "allowxperm", "test101c", "test101c", "infoflow7",
set([0x9011, 0x9012, 0x9013]), xperm="ioctl")
self.validate_rule(r[3], "allowxperm", "test101d", "test101d", "infoflow7",
set([0x9011, 0x9012, 0x9013, 0x9014]), xperm="ioctl")
def test_101_xperm_equal(self):
"""Xperm rule query match equal perm set."""
q = TERuleQuery(self.p, xperms=[(0x9011, 0x9013)], xperms_equal=True)
r = sorted(q.results())
self.assertEqual(len(r), 1)
self.validate_rule(r[0], "allowxperm", "test101c", "test101c", "infoflow7",
set([0x9011, 0x9012, 0x9013]), xperm="ioctl")

View File

@ -188,17 +188,6 @@ allowxperm test8a1 test8a1:infoflow ioctl 0x9999;
allowxperm test8a2 test8a2:infoflow ioctl 0x1111;
allowxperm test8FAIL self:infoflow ioctl 0x5555;
# test 9
# ruletype: unset
# source: unset
# target: unset
# class: infoflow2, no regex
# perms: unset
type test9;
allowxperm test9 self:infoflow ioctl 0x9999;
allowxperm test9 self:infoflow2 ioctl { 0x5411 0x5451 };
# test 10
# ruletype: unset
# source: unset
@ -231,6 +220,31 @@ type test14;
auditallowxperm test14 self:infoflow7 ioctl 0x1234;
dontauditxperm test14 self:infoflow7 ioctl 0x4321;
# test 100
# ruletype: neverallow, neverallowxperm
# source: unset
# target: unset
# class: unset
# perms: ioctl (standard)
type test100;
neverallow test100 system:infoflow2 { ioctl hi_w };
neverallowxperm test100 self:infoflow2 ioctl 0x1234;
# test 101
# ruletype: unset
# source: unset
# target: unset
# class: unset
# perms: 0x9011-0x9013
type test101a;
type test101b;
type test101c;
type test101d;
allowxperm test101a self:infoflow7 ioctl 0x9011;
allowxperm test101b self:infoflow7 ioctl { 0x9011-0x9012 };
allowxperm test101c self:infoflow7 ioctl { 0x9011-0x9013 };
allowxperm test101d self:infoflow7 ioctl { 0x9011-0x9014 };
############# END XPERM ############################
role system;