Re: [RFC] Cascade: a high level SELinux policy language

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

 



On 11/5/2021 3:19 PM, James Carter wrote:
On Thu, Nov 4, 2021 at 2:14 PM Daniel Burgener
<dburgener@xxxxxxxxxxxxxxxxxxx> wrote:

We have been working over the past few months on a new high level
language for specifying SELinux policy, in line with the original intent
of CIL, to enable the creation of high level languages that compile into
CIL.


If you ever feel like CIL doesn't quite do what you need or that it
doesn't work as expected, please let me know.

Absolutely. So far, CIL has worked great for what I need. I'll definitely contribute or reach out if I run into issues though. I hope/expect that the overall development will exercise some CIL corner cases that may not have gotten a lot of use in the past, although that remains to be seen.


Our objective is to create a language that enables the efficient
creation of useful abstractions by policy experts while enabling those
abstractions to be easily usable by non-experts who may contribute to
portions of the policy.

The design is heavily influenced by Object Oriented principles, with a
goal of enabling the efficient creation of type hierarchies and
eliminating boilerplate through the use of inheritance.  The use of
"virtual" types, (which compile into attributes) allows both attribute
like behavior, and also the creation of inherited member functions,
allowing for interfaces as in refpolicy without the redundant
boilerplate.  Another key feature is "resource association" which makes
explicit the connections between domains and associated types such as
tmp files.  This feature allows for common patterns (such as setting up
a tmp file with a domain transition rule and manage access) to be done
automatically behind the scenes, minimizing the chance of mistakes and
allowing policy developers to focus more on security decisions.


I realize that many of my questions below will be answered with
"future work", so don't feel like you need to explain in great detail
if that is the case.

How different is the inheritance in Cascade as compared to CIL.
Obviously, in CIL it is not required, where in Cascade it is a very
important part. There is also the use of "this" in Cascade.

I definitely have less CIL expertise than you, so please correct me if I have anything inaccurate about CIL. I don't think there are any fundamental differences/incompatibilities between CIL inheritance and Cascade inheritance, at least not in the big picture. They're both generally aiming at solving a similar problem in a similar manner. They both inherit rules and create name mangled derived types for children. In contrast to CIL, Cascade intermingles attributes and inheritance. So if I inherit from a parent, I automatically have an attribute for all children that I can reference elsewhere. Cascade inheritance is also used to check function arguments. So I can have a function that only takes children of the foo type and will throw a compiler error if used otherwise. I don't *think* CIL has something similar to that?

I think one of the bigger distinctions (across the board, but including inheritance) is that syntactic sugar is an explicit non-goal of CIL, and an explicit goal of Cascade. Our objective is to make inheritance easier to use and natural feeling for developers who are familiar with object oriented programming languages. I'll leave it up to others to decide whether we've succeeded there, and/or whether we can succeed there as we continue to develop.


It seems like Cascade is resolving all of its inheritance before
writing out the CIL. My guess is that inheritance is such a core part
of Cascade that using CIL's inheritance would make no sense. Is that
true? Or did you just not like the way CIL does it?

This was mostly just around the centrality of the inheritance feature to Cascade. It seemed like we'd have more flexibility doing that one by hand so to speak. Our overall goal was to avoid reimplementing things that CIL already does, and just compile into the underlying CIL feature. It's entirely possible that we could have/could in the future make more use of CIL's inheritance functionality. That would be a win in terms of interoperability. Inheritance of non-virtual types is on my TODO list, and when I get to that, I'll do some more in depth digging on whether we can lean more into existing CIL functionality here, which might make that use case easier. That said, doing name mangling in our code rather than leaving it to CIL allows us the ability to have more control over applying things like annotations. Annotations aren't used yet to their full potential, but my hope is that they can ultimately be used to provide a set of "debug symbols" consumed by audit2cascade and other tooling, in order to improve automated response to detected AVC denials, and policy discoverability for non-experts trying to understand said denials. I *think* that as we aim to continue down that path, having full control over the list of types in the policy from inside the Cascade compiler will be important.


I was surprised that casc only take a single file. Do you expect the
policies to be simple enough to do in one file?

Future work. The library backend supports it, but I haven't updated the front end yet.


Since there is only one file, I guess there is no concept of modules
for Cascade? And this means there is no need for something like an
optional block because all of the policy would be compiled at once?

Future work. Our primary internal use case that we hope to migrate for Cascade for involves compiling policies for multiple systems from the same repo, so we'll definitely need module support. In particular the ability to mix and match groups of modules easily is important to us. What I'd like to do is add new `system {}` and `module {}` blocks that integrate naturally with everything else, and add options to casc to support easily building multiple systems. On our existing refpolicy based setup, we have to do a lot of shell script processing to get everything to work well, and it's challenging to maintain.

In terms of optional blocks, Chris and I have argued about optional a few times, and part of the reason there's nothing about optional so far is because we'd like to solicit community feedback there. My personal view is that explicitly marking statements as optional is tedious and error prone. But I don't have a really slam dunk "clearly better" solution to propose yet at this point. I have a few ideas, but they all need to be more thoroughly thought out and there are some holes and issues to address. I viewed this feature as non-essential for an initial proof of concept, and am glad that we can have design discussions about it in the open.

So in short, yes, I think the ability to differentiate that certain rules are required for a module to work and others are optional is definitely needed. But I'm not yet set on what the best way to do that is. One key goal here is that a developer of a component should be able to add policy with fairly minimal knowledge of SELinux. I'd prefer it if most of the time they could do the right thing without knowing about optional, but I'm not yet sure what the best/cleanest way to achieve that will be.


It looks like classes, mls statements, and sids are all automatically
created in CIL. Is there a way to specify these things in Cascade or,
since these things are almost always the same, are these low-level
details something Cascade is not worried about.

Yes, currently these things are all hard-coded in CIL. My goal in general is to have sensible defaults for people who don't care, but allow override for people who do. So where I'd like to get to in the long term is to continue to define these things in code, but allow policy developers or either modify the defaults, or completely override them with their own implementations. That's future work.


What about roles and users. I see the keywords, but how are they going to work?

Future work. The overall goal would be for users who say "I don't need UBAC" or "I don't need RBAC", then they could just get something with automatic users and roles, like as in Android, with zero effort. But we definitely want fully featured UBAC and RBAC support available for those who need it.


Thanks for letting us know about this work. It looks interesting.
Jim

Thanks!  Thanks for your feedback/questions.




The core language functionality is written as a library, which will
hopefully enable the easy creation of associated tooling and plugins
that build on top of that library.  It is our hope that this
architecture will assist an expansion of available tooling to aid policy
developers in their work.

This is still a very early prototype and so some functionality may be
missing or incomplete, but we wanted to make what we have so far
available for community feedback and discussion as we continue development.

You can find the code and associated documentation at
https://github.com/dburgener/cascade

I hope this is something that people will find useful and welcome
feedback and contributions as we aim towards the goal of enabling
smoother policy development.

-Daniel




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

  Powered by Linux