mirror of
https://github.com/SELinuxProject/setools
synced 2025-04-01 22:58:12 +00:00
Complete TERuleQuery changes for extended permission rules.
Related to #73.
This commit is contained in:
parent
c56e01bc8c
commit
a9cd2248e9
@ -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
|
||||
#
|
||||
|
@ -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)
|
||||
|
@ -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")
|
||||
|
@ -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;
|
Loading…
Reference in New Issue
Block a user