Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for nlmsg extended permission #138

Merged
merged 4 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on: [push, pull_request]

env:
# This should be the minimum version required to run setools:
SELINUX_USERSPACE_VERSION: 3.2
SELINUX_USERSPACE_VERSION: main

# GitHub doesn't support building env
# vars from others in this block.
Expand Down
2 changes: 1 addition & 1 deletion setools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
IoctlSet, Iomemcon, IomemconRange, Ioportcon, IoportconRange, Level, LevelDecl, MLSRule, \
Netifcon, Nodecon, ObjClass, Pcidevicecon, Pirqcon, PolicyCapability, Portcon, PortconRange, \
Range, Role, RoleAllow, RoleTransition, Sensitivity, TERule, TruthTableRow, Type, \
TypeAttribute, User, Validatetrans
TypeAttribute, User, Validatetrans, XpermSet

# Exceptions
from . import exception
Expand Down
12 changes: 6 additions & 6 deletions setools/diff/terules.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ class ModifiedAVRuleXperm(DifferenceResult):
"""Difference details for a modified access vector rule."""

rule: policyrep.AVRuleXperm
added_perms: policyrep.IoctlSet
removed_perms: policyrep.IoctlSet
matched_perms: policyrep.IoctlSet
added_perms: policyrep.XpermSet
removed_perms: policyrep.XpermSet
matched_perms: policyrep.XpermSet


@dataclass(frozen=True, order=True)
Expand Down Expand Up @@ -365,9 +365,9 @@ def diff(self) -> None:
if added_perms or removed_perms:
modified.append(
ModifiedAVRuleXperm(left_rule.origin,
policyrep.IoctlSet(added_perms),
policyrep.IoctlSet(removed_perms),
policyrep.IoctlSet(p[0] for p in matched_perms)))
policyrep.XpermSet(added_perms),
policyrep.XpermSet(removed_perms),
policyrep.XpermSet(p[0] for p in matched_perms)))

setattr(self, f"added_{ruletype}s", set(a.origin for a in added))
setattr(self, f"removed_{ruletype}s", set(r.origin for r in removed))
Expand Down
8 changes: 5 additions & 3 deletions setools/policyrep.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class PolicyRule(PolicyObject):
target: "PolicySymbol" = ...
tclass: "ObjClass" = ...
xperm_type: str = ...
perms: frozenset[str] | "IoctlSet" = ...
perms: frozenset[str] | "XpermSet" = ...
default: PolicyObject = ...
filename: str = ...
def enabled(self, **kwargs) -> bool: ...
Expand Down Expand Up @@ -101,7 +101,7 @@ class AVRule(BaseTERule):

class AVRuleXperm(BaseTERule):
default: NoReturn = ...
perms: "IoctlSet" = ...
perms: "XpermSet" = ...
xperm_type: str = ...
def expand(self, *args, **kwargs) -> Iterable["AVRuleXperm"]: ...

Expand Down Expand Up @@ -247,9 +247,11 @@ class IbpkeyconRange:
class InitialSID(Ocontext):
name: str = ...

class IoctlSet(frozenset[int]):
class XpermSet(frozenset[int]):
def ranges(self) -> int: ...

class IoctlSet(XpermSet): ...

class Iomemcon(Ocontext):
addr: "IomemconRange" = ...

Expand Down
2 changes: 2 additions & 0 deletions setools/policyrep/sepol.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ cdef extern from "<sepol/policydb/avtab.h>":
#
cdef int AVTAB_XPERMS_IOCTLFUNCTION
cdef int AVTAB_XPERMS_IOCTLDRIVER
cdef int AVTAB_XPERMS_NLMSG

cdef struct avtab_extended_perms:
uint8_t specified
Expand Down Expand Up @@ -437,6 +438,7 @@ cdef extern from "<sepol/policydb/policydb.h>":
#
cdef int AVRULE_XPERMS_IOCTLFUNCTION
cdef int AVRULE_XPERMS_IOCTLDRIVER
cdef int AVRULE_XPERMS_NLMSG
cdef int EXTENDED_PERMS_LEN

cdef struct av_extended_perms:
Expand Down
25 changes: 18 additions & 7 deletions setools/policyrep/terule.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,11 @@ cdef class AVRule(BaseTERule):
return self.rule_string


cdef class IoctlSet(frozenset):
cdef class XpermSet(frozenset):

"""
A set with overridden string functions which compresses
the output into ioctl ranges instead of individual elements.
the output into ioctl/nlmsg ranges instead of individual elements.
"""

def __format__(self, spec):
Expand Down Expand Up @@ -249,7 +249,7 @@ cdef class IoctlSet(frozenset):
elif spec == ",":
return ", ".join(shortlist)
else:
return super(IoctlSet, self).__format__(spec)
return super().__format__(spec)

def __str__(self):
return f"{self}"
Expand All @@ -267,12 +267,20 @@ cdef class IoctlSet(frozenset):
sorted(self), key=lambda k, c=itertools.count(): k - next(c)))


cdef class IoctlSet(XpermSet):

def __init__(self, *args, **kwargs):
log = logging.getLogger(__name__)
log.warning("IoctlSet is deprecated, use XpermSet instead.")
super().__init__(*args, **kwargs)


cdef class AVRuleXperm(BaseTERule):

"""An extended permission access vector type enforcement rule."""

cdef:
readonly IoctlSet perms
readonly XpermSet perms
readonly str xperm_type

@staticmethod
Expand All @@ -292,9 +300,10 @@ cdef class AVRuleXperm(BaseTERule):
#
for curr in range(len):
if sepol.xperm_test(curr, xperms.perms):
if xperms.specified & sepol.AVTAB_XPERMS_IOCTLFUNCTION:
if (xperms.specified == sepol.AVTAB_XPERMS_IOCTLFUNCTION \
or xperms.specified == sepol.AVTAB_XPERMS_NLMSG):
perms.add(xperms.driver << 8 | curr)
elif xperms.specified & sepol.AVTAB_XPERMS_IOCTLDRIVER:
elif xperms.specified == sepol.AVTAB_XPERMS_IOCTLDRIVER:
base_value = curr << 8
perms.update(range(base_value, base_value + 0x100))
else:
Expand All @@ -309,6 +318,8 @@ cdef class AVRuleXperm(BaseTERule):
if datum.xperms.specified == sepol.AVTAB_XPERMS_IOCTLFUNCTION \
or datum.xperms.specified == sepol.AVTAB_XPERMS_IOCTLDRIVER:
xperm_type = intern("ioctl")
elif datum.xperms.specified == sepol.AVTAB_XPERMS_NLMSG:
xperm_type = intern("nlmsg")
else:
raise LowLevelPolicyError(f"Unknown extended permission: {datum.xperms.specified}")

Expand All @@ -322,7 +333,7 @@ cdef class AVRuleXperm(BaseTERule):
r.source = type_or_attr_factory(policy, policy.type_value_to_datum(key.source_type - 1))
r.target = type_or_attr_factory(policy, policy.type_value_to_datum(key.target_type - 1))
r.tclass = ObjClass.factory(policy, policy.class_value_to_datum(key.target_class - 1))
r.perms = IoctlSet(perms)
r.perms = XpermSet(perms)
r.extended = True
r.xperm_type = xperm_type
r._conditional = conditional
Expand Down
6 changes: 3 additions & 3 deletions setools/terulequery.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ class TERuleQuery(mixins.MatchObjClass, mixins.MatchPermission, query.PolicyQuer
boolean = CriteriaSetDescriptor[policyrep.Boolean]("boolean_regex", "lookup_boolean")
boolean_regex: bool = False
boolean_equal: bool = False
_xperms: policyrep.IoctlSet | None = None
_xperms: policyrep.XpermSet | None = None
xperms_equal: bool = False

@property
def xperms(self) -> policyrep.IoctlSet | None:
def xperms(self) -> policyrep.XpermSet | None:
return self._xperms

@xperms.setter
Expand All @@ -104,7 +104,7 @@ def xperms(self, value: Iterable[tuple[int, int]] | None) -> None:

pending_xperms.update(i for i in range(low, high + 1))

self._xperms = policyrep.IoctlSet(pending_xperms)
self._xperms = policyrep.XpermSet(pending_xperms)
else:
self._xperms = None

Expand Down
5 changes: 3 additions & 2 deletions tests/library/policyrep/rules.conf
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ common infoflow
low_r
med_r
hi_r
ioctl
ioctl
nlmsg
}

class infoflow
Expand Down Expand Up @@ -120,7 +121,7 @@ if (a_bool) {
type_transition type31b system:infoflow4 type30 "the_filename";

allowxperm type30 type31a:infoflow ioctl 0x00ff;
auditallowxperm type31a type31b:infoflow ioctl { 0x001-0x0003 };
auditallowxperm type31a type31b:infoflow nlmsg { 0x001-0x0003 };

allow system self:infoflow hi_w;
range_transition type30 system:infoflow7 s0:c1 - s2:c0.c4;
Expand Down
Loading
Loading