--- Kyle Moffett <mrmacman_g4@xxxxxxx> wrote:On Aug 11, 2007, at 21:21:55, Casey Schaufler wrote:--- Kyle Moffett <mrmacman_g4@xxxxxxx> wrote:I was considering compiling the complete list, but such an exercise would take me at least an hour to do properly and which categories individual permissions should be placed in could be argued for weeks.
I will be happy to consider your arguement when you are willing to present the complete argument.
Here's my complete argument:
Regardless of how you categorize "read", "write", "execute", and "doesnt-need-protection" in your policy language, I can write an SELinux policy and a list of labels which expresses that policy. Moreover, without too much work I can probably write a Perl script to do it for you. On the other hand I can only do that if you tell me exactly how you want to categorize those things, though. In my personal opinion they cannot be reasonably categorized without breaking all sorts of tools or leaving gaping holes; precisely the reason that SELinux uses such a fine-grained list.
This identifies an important design philosophy issue, that being what granularity is appropriate. I have no interest in composing a description of Smack at the granularity that SELinux uses.
The point you make, that you need to have that in order to create a policy description, is one of the reasons for Smack. Simplified.
Ok, you want sample policy to match your "MLS" sample? For convenience here's one more macro:
define(`rx',`r(`$1',`$2') x(`$1',`$2')')
type unclass;
type c;
type s;
type ts;
rx(c, unclass)
rx(s, c)
rx(s, unclass)
rx(ts, s)
rx(ts, c)
rx(ts, unclass)
In case you don't have the policy you typed into your email, it looks almost identical with a few exceptions for slightly modified syntax:C Unclass rx
S C rx
S Unclass rx
TS S rx
TS C rx
TS Unclass rx
Yup. Your macro invocations look very much like the Smack specification. Your macro definitions are of course unnecessary in Smack, and you really ought to be using the MLS labels SELinux supports, and you need a base policy underneath this.
Whoops, I think I must have smashed the delete key or something while sending. Here's the paragraphs which got elided:
Well, yes, but a policy which completely ignores future expandability can't be expanded upon regardless. It would also be very hard to add new policy without a lot of duplication under your system. On the other hand, with SELinux you can very easily add attribute-based policy so adding new capabilities is as simple as sticking existing attributes on newly defined types. For example:
type my_log_t, file_type, log_file;
type my_log_daemon, daemon;
Right there I just gave permission for the logrotate to recycle files labelled my_log_t, which the sysadmin and audit admin can also read (and the audit admin can delete). I also gave permission for my daemon to send SIGCHLD to init, and for init/ initscripts to send it a SIGTERM/SIGQUIT. All without writing a SINGLE policy rule. Basically all of those existing behaviors are found in allow rules built on the "file_type", "log_file", and "daemon" attributes.
Ah, now you're refering to the reference policy, right?
They can be added or changed one by one as required while the system is running, and there are uses that exploit that. One example is to put the label "Game" on certain programs and:
at 8:00am "Worker Game no"
at 5:00pm "Worker Game x"
Thus Worker processes can access Game files only during off hours.
This is fundamentally broken:
[...]
Secondly, you can already do the same thing with DAC and a PAM groups-from-time-of-day module, I don't see why such a thing is special enough to need MAC. Thirdly, I could do exactly the same thing with an SELinux boolean and a cronjob (once we get proper revoke support):
There is usually a way to address any particular problem using DAC, it's often sufficiently painful that MAC looks like a better approach.
Your boolean solution requires more forthought than the Smack rule solution, but I'll give it to you once you've fleshed out your "##" lines.
## Rule to allow cron to tweak the "can_play_games" boolean value
if (can_play_games) {
## Insert game-playing allow rules here
}
As far as relabeling the file system goes, the rules apply to processes and objects, not to programs. The label on a program describes who can access it, it will run with the label of the process that exec's it. A change in the rules does not require a change to the labels on the file system for things to work according to the rules of engagement.
By this logic, every program will always have the same label, unless you recode every program to explicitly change it when it starts; precisely the thing that the SELinux type transitions were designed to avoid.
Yes. This is the way it should be. A small set of very carefully analysed programs that change labels under carefully controlled circumstances is what I want. login, sshd, cron, special purpose launchers. Written with the assumption that they will be attacked.
When you change the meaning of new types, you clearly would need to first reload the policy then relaunch programs or relabel files to take advantage of the new types, otherwise they would be categorically ignored by the system.
I'm sorry, but again, I don't know what you mean by "changing the meaning of new types".
Oh, say something like "Oh, drat, I wanted this daemon to run as some other type".
Sorry, "type" is a meaningless attribute in Smack.
Unless you relabel the files and relaunch the daemon the system will have no idea how the system will change. And if you let arbitrary root processes relabel things on the fly then you've lost all the security advantages to a MAC system.
MAC systems have been behaving this way for decades. SELinux is the exception, not the rule on this.
I think you may be making assumptions about the behaviour of SELinux based on what other OSes do which don't hold:
(a) SELinux does not care about user id, current directory, time of day, etc. It cares solely about 3 things: the Subject, the Object, and the Action. For example, if an init script attempts to execute the apache binary then SELinux gets the following data for parameters: subject="system_u:system_r:initrc_t:SystemLow- SystemHigh" object="system_u:object_r:httpd_exec_t:SystemLow" action="file->execute".
Yes, and each of the components of the subject and object contexts is dependent on a more circumstances than I'd care to deal with. You've demonstrated that SELinux implements fine granularity.
(b) SELinux does NOT have a capability which overrides it. If you want to do something that the policy categorically does not allow, you have 2 choices: change the policy or disable SELinux. You can also use a policy which disables both of those options
Yup. I think that's bad.
And Bell & LaPadula using a combination of levels and categories is probably the Smack worst case. But guess what? The dig against that policy has always been that no one wanted to combine levels and categories.
Ok, fine, how does "moving data around a system" require anything more than bog-standard user-level privileges? Normal users under Linux are not permitted to change "security.*" attributes at all, but they may bind to sockets, etc. You can define a "capability" which lets you do all that, but then you're just blindly giving processes more privileges than they need to complete an operation. Why should you get the "rename all files" priv when all you need is "Make my log files get $LABEL when I put them in / var/log/mydaemon/"?
Privilege granularity is a seperate issue. Smack uses Linux privilege machanisms and is happy to do so.
Why should it? Admittedly, moving data from "TopSecret" to "Secret" requires a process labeled with a range including at least "S-TS" *and* with the MLS "read-to-clearance" attribute, but you can be as stingy with that attribute as you like.
Yup. And plenty of people like you think that is really spiffy.
Please explain why you think it isn't?
I grew up believing that downgrading classified information should always be an explicit, concious act.
You can call them "process capabilities" or "magic attributes", they're the same thing, just more fine-grained. Instead of (Note: r1 == subject role, r2 == target role, t2 == target type):
mlsconstrain process transition ( (r1 == r2) || (t1 == i_am_a_role_changing_capability) )
you have (Note: t1 == subject type):
mlsconstrain process transition ( (r1 == r2) || (r1 == system_r && t1 == i_am_a_login_process && t2 == i_am_a_user_entrypoint) )
The latter is like the former, except instead of one single ultimate "change-any-role" capability, you have a capability which allows a system login process to change roles *ONLY* if it's also changing to a user entrypoint. Please tell me which you think is more secure.
Don't look at me. A well written program could do fine with either.
So the implicit labeling of files actually restricts every process *FURTHER*. They no longer have even an inkling of a choice about file labeling, and that's a GOOD thing.
That's true about Smack, you know. The process has no choice about the label that the files get.
So how do you selectively label files based on criteria such as "where did I get put"? How do you distinguish between a "log file" which is create-and-append-only, a "database file" which I can modify however I want to, and a "unix socket" which I can bind in /var/run and get connections from user processes?
I don't. They're all objects.
Thank you for your comments. I hope that I have made the behavior and value of Smack clearer in responding to them.
You're welcome. I endeavor to poke my nose into every little LSM- related corner in the kernel, this one included.
Why?