[cap-talk] SELinux vs. capabilities
Jonathan S. Shapiro
shap at eros-os.com
Fri Jul 27 00:50:04 EDT 2007
Since SELinux is pretty effective at guarding daemon behavior, it seems
worthwhile to ask some questions:
1. Can SELinux behavior be implemented by capabilities?
2. What is the relationship, if any, between SELinux and
capabilities? Do mandatory controls serve a purpose?
3. Can SELinux approximate capability behavior?
SELinux operates on triples (domain, operation, type). Each category is
statically defined [the policy can be modified on the fly, but a given
policy instance has some particular set of domains, operations, and
types]. An executable is assigned a domain based on its type at exec
time. It is possible for a running application to undergo a domain
relabeling as a consequence of an action. I will ignore this for the
moment. I will also ignore "roles" and "contexts" for the moment.
SELinux, by the way, guards the SENDFD operation. The operation may be
prohibited, but the descriptor transferred is not altered if transfer is
In practice, file types are determined by path. While individual type
labels can be changed, there is a label restoration utility that is run
often enough that such changes are not reliably durable. This utility
consults a table of regexp->type mappings. The same table is consulted
whenever new files are created. We may therefore equate types to equate
to a set of path regular expressions. The mapping from paths to types is
injective. Every file has exactly one type.
This model cannot be directly expressed in capabilities alone, but it
can be constructed on top of capabilities. Assume that there is a single
file name space, and that the file server maintains the SELinux regular
expression rule set. Each domain id is assigned a unique protected
payload value. The file server uses the protected payload value as the
domain id and runs the regular expression set to determine the file
type. Based on this it determines whether the action is permitted.
Now this obviously isn't a capability design. It relies heavily on the
fact that the mapping from file names to sensitive content is stable,
and it relies completely on use of subject IDs.
What are its pros and cons relative to capabilities?
1. The policy is stated orthogonal to the object fabric. This can be
important. For example: yesterday I needed to alter the policy to allow
rsync to read anything that was "public" via the web server, and in
addition a second file tree that is not public. [In hindsight the latter
was stupid; there was a better way.] In essence I wanted to unify the
rsync_t domain and the httpd_t domain, but only for read operations.
This was possible.
2. The policy is, in abstract, comprehensible. SELinux itself is not
well documented, but it could be.
3. It is possible to get an overview of what the policy is. This is
difficult to abstract in a pure capability model, as there is no single
point of view authorized to do so. It is certainly possible to build
capability systems that can do this. It is also possible to build
capability systems that cannot.
1. Does not address dynamic or discretionary policy.
So, to answer my questions above:
1. SELinux can be implemented on top of capability systems. The current
constructor/factory model can be used more or less directly.
2. SELinux has a very limited ability to support dynamism. While the
domain of a running program can transition based on its actions,
this is statically specified.
3. SELinux cannot realistically implement capabilities. To do so it
would have to operate on internal object IDs. The manageability of
SELinux relies on the fact that the name space is sensible to humans
in order to achieve its manageability.
Now broadly speaking, I think that SELinux is too complicated and too
opaque. It is not clear if this is a problem resulting from lack of
tools or if this is inherent in type enforcement (TE) and Role-Based
Access Control. It is interesting to look at AppArmor as an illustrative
example of a simpler, more manageable (but less powerful) approach.
I think, however, that we tend in this forum to focus our attention on
discretionary problems, and this leads us to prefer discretionary
(capability) solutions. I think it is worthwhile to explore how
capabilities can/should be applied to things like server permission
management (such as my problem with rsync). If we conclude that
mandatory controls are useful, it has implications for name space
design, labeling design, and manageability that I think we should talk
Jonathan S. Shapiro, Ph.D.
The EROS Group, LLC
More information about the cap-talk