Policy capabilities: when to use and complications with using

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Looking at adding a map permission for mmap [1], and thinking about
whether it needs to be wrapped by a policy capability.  On the one
hand, we made the open permission depend on a policy capability, but on
the other hand, we haven't done that for other cases where we simply
added a check of a new permission (recent examples include prlimit
checking and module_load).  Compatibility for new permission checks is
generally covered in Linux distributions via handle_unknown=allow, and
in Android where handle_unknown=deny, the kernel and policy are not
independently updated so we can keep them properly synchronized without
needing such compatibility measures.

It seems like we generally reserve the use of policy capabilities for
when there is a more fundamental change in logic that wouldn't be
covered by handle_unknown.  All of the current policy capabilities
except for open_perms seem to fit into that category; they change what
permissions/classes are checked rather than merely adding a new check,
or they change when checks are applied, or they alter labeling
behavior.  Even if that is our standard, we haven't consistently
defined new policy capabilities for all such changes, e.g. for
distinguishing non-init user namespace capability checks (commit
8e4ff6f228e4722cac74db716e308d1da33d744f) or for the earlier updating
of netlink socket classes (commit
6c6d2e9bde1c1c87a7ead806f8f5e2181d41a652).  Those changes don't break
existing policies because of handle_unknown=allow, but since they are
actually changing what is checked and not merely adding new checks,
they technically ought to have been wrapped (with handle_unknown=allow,
they could end up allowing what would have been previously denied due
to changes in the classes).

Part of the reason that we tend to not introduce a new policy
capability more often is that it is painful to do so currently.  We
have to patch libsepol to recognize the new capability and patch the
policy to declare it (although for the latter we can now declare them
via a CIL module without modifying the base policy).  And since the
policy or module won't build without the updated libsepol, we can't
turn on the capability by default in refpolicy without making it
dependent on a new libsepol version.  That's why extended_socket_class
isn't yet enabled in refpolicy, for example.  That causes enablement
and adoption to lag behind.  It also makes it harder to test the new
kernel feature in the first place.

We could possibly look into lighter weight support for policy
capabilities.  If the policy compiler toolchain left the capability
names as strings in the kernel policy (new binary format version), then
we would no longer need to update libsepol for each new policy
capability.  The kernel would then turn the list into the bitmap
internally.  The downside is that we would lose validation of the
capability names when policy is built, and it isn't clear how the
kernel should handle unknown names (presently the kernel will simply
ignore any unknown capabilities in the bitmap).  Failing at policy load
time would mean we can't enable the capability in policy without making
it depend on a particular kernel version.

The lack of any direct relationship between policy capabilities and the
classes/permissions they affect also can be misleading.  For example,
someone booting a recent kernel might see warnings about undefined
classes introduced by the extended_socket_class feature and add those
class definitions to their policy, which will silence the kernel
warning and make them think that they are actually using those classes
now.  But they won't actually get used until they declare the
capability too in their policy, and the kernel doesn't warn about that
(nor does it necessarily make sense to do so, since that may be a
conscious choice by the policy author).  The kernel could however log
each policy capability and its state as part of its normal logging and
leave it up to the reader to decide whether those values are correct or
not.  We also had talked originally about checkpolicy and friends
possibly warning on inconsistencies, while leaving it up to the policy
author.

So:

1) Should we investigate lighter weight support for policy
capabilities, and if so, how?

2) Should the kernel log information about enabled/disabled policy
capabilities in much the same manner as it does for undefined
classes/permissions?

3) Should the policy compiler toolchain warn the user if a policy
capability is not declared and classes/permissions are used in rules
that will only be used if that policy capability is declared?  And
similarly if a policy capability is declared but the corresponding
classes/permissions are not used in any rules?

4) Do we need/want a policy capability for map permission and other
cases where we are only adding a new permission check? Or should we
continue to reserve them for cases not addressed via handle_unknown?

[1] https://github.com/SELinuxProject/selinux-kernel/issues/13



[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux