From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?iso-8859-2?q?T=F6r=F6k_Edwin?= To: "Stephen Smalley" Subject: Re: Labeling only policy and problems with booleans Date: Wed, 26 Apr 2006 21:13:00 +0300 Cc: "Joshua Brindle" , "Christopher J. PeBenito" , selinux@tycho.nsa.gov, fireflier-devel@lists.sourceforge.net, marius@cs.utt.ro References: <200604021240.21290.edwin@gurde.com> <200604232258.14004.edwin.torok@level7.ro> <1146058670.28745.117.camel@moss-spartans.epoch.ncsc.mil> In-Reply-To: <1146058670.28745.117.camel@moss-spartans.epoch.ncsc.mil> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-2" Message-Id: <200604262113.01211.edwin@gurde.com> Sender: owner-selinux@tycho.nsa.gov List-Id: selinux@tycho.nsa.gov On Wednesday 26 April 2006 16:37, Stephen Smalley wrote: > On Sun, 2006-04-23 at 22:58 +0300, Török Edwin wrote: > > domain_auto_trans(unlabeled_t,myapp_exec_t,myapp_t) > > No process should be running in unlabeled_t (a process might be > re-mapped to unlabeled_t if its type was removed from policy and policy > was reloaded while the process was still running, but this would quickly > lead to death for the process as it would lose access to its resources). Ok, I won't add rules for unlabeled_t. > > But why didn't the booleans work? I tried setting their default values in > > booleans.conf to true, and still the same result, they weren' > > t taken into consideration. > > I think we need more details to see whether this is a bug or not. > What > version of refpolicy? 20060307 > What version of checkpolicy? checkpolicy 1.30-1, runnning on AMD64, kernel 2.6.16, debian sid. I also tried:checkpolicy-1.30.3-1.fc5 on fedora core 5. The virtual machine I tested my policy is emulating an x86_64 too. I tried loading the policies generated by both versions, and I had the "boolean problem" with both. > There was a problem > with the boolean mapping at link time with the optionals-in-base changes > to refpolicy and certain versions of checkpolicy, but I think that has > been resolved in the current version (although optionals-in-base still > doesn't work properly, but that doesn't affect you as long as you are > building everything you need into base). If I have only the base module loaded (and anything else besides unconfined.pp) then setting secure_mode_policyload works as expected. However if I load unconfined.pp, I can change the policy even after secure_mode_policyload As soon as I remove unconfined.pp (and its dependencies), secure_mode_policyload works again. > > > (btw, I also ran into a make bug: > > http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=358903, I hope this > > booleans problems isn't another build-tool related bug, if needed I can > > make the compiled policy module available for analysis) > > Yes, that would be helpful. The policy where I had unconfined linked (boolean not working) http://edwintorok.googlepages.com/policybad.tar.gz The policy where I didn't have unconfined linked: http://edwintorok.googlepages.com/policyok.tar.gz kernel messages: http://edwintorok.googlepages.com/messages full build directory: http://edwintorok.googlepages.com/refpolicy.tgz Let me know if anything else is needed to trace the problem. There is another thing that worries me. I was able to do mknod xx c 1 2 creating an equivalent of /dev/kmem, and it wasn't labeled memory_device_t, it was labeled unlabeled_t. So I guess giving access to unlabeled_t files is very dangerous (as you say below). I assume one could exploit this by writing a program that creates a kmem equivalent, and then he can do anything he wishes, including replacing policy, loading another kernel module, patch syscalls...., am I right? > > Originally, attributes were all expanded when policy was compiled, and > the kernel just dealt with the individual pairs. But current kernels > and policies retain attributes in the rules when feasible, so the > representation is more compact if you use attributes in your rules. So > you save memory that way. Runtime processing itself is largely > unaffected, as the access vector cache provides most of the security > decisions, so security server computations are infrequent. So I shouldn't worry about the number of types/attributes in my policy as far as performance is concerned. I might optimize when the policy is final, to save some memory. > > > Also since all programs will have unlabeled_t by default, there is no > > point to do an initial relabeling, so either: > > - mount -o context=unconfined_t > > - do nothing, and the programs will get by default unlabeled_t, or > > file_t, right? > > Using unlabeled_t in this way is a bad idea; it is used internally for > various purposes to identity unlabeled entities or entities that have > become unlabeled due to label invalidation. I'll avoid using unlabeled_t. What is the best practice to do when: most of the programs on the system will run as unconfined_t, so they'll all have the same (default) label (on my system file_t seems to be the default label) except: - devices in /dev (handled by udev policy?) - selinux policy loading programs (loadpolicy, semodule) But I do want to be able to label individual files (when fireflier generates policies for them). If I don't run setfiles, and I run restorecon only for the: selinux policy loading programs, and fireflier, will that be safe? (will an unlabeled program be able to gain access to another domain besides unconfined_t) Also, should I consider doing the policy loading myself in fireflier (via libselinux,libsemanage...) instead of relying on an external program? > > > One of the other goals is the ability to be able to boot the system in > > enforcing mode, without any manual policy modifications. If all programs > > are unconfined_t/default_t will this be possible? > > If everything is unconfined, then naturally enforcing mode has no real > impact on behavior. Ok. But let me clarify, by unconfined_t I don't mean unconfined_t from the targeted policy, since that has policy loading allowed. I want to allow unconfined_t everything except: - loading policy - changing labels - kernel module loading (boolean controlled, if I get booleans working) - changing iptables rules - writing to raw memory Fireflier doesn't aim to be a full security solution, I just want it to create proper labels for skfilter to use, and as such there should be no way for an unconfined_t process to change labels/load policy. I however don't care (maybe in a future version of fireflier I will) if an unconfined_t writes to raw disk devices for example, etc. as long as it doesn't "escape" the packet filtering rules. I could have just created a policy that imposes no restrictions (like secure_mode_policyload, protection from raw memory writes, protection from security context transitions), since a program that is able to do that is root, and if he is root he could just 'iptables -F', and all is over. But I considered to provide some of the protections of the targeted policy, since if people see fireflier creates&uses selinux policies, will think "ah it uses selinux, this must be safe, so if I put this iptables rule here it will make sure that only this program is allowed to receive on that port. Not even if somebody gains root, will he be able to alter my iptables rules". I'll document clearly that fireflier doesn't aim at protecting you from root exploits, and the actions of root; but I think that offering "some" protection against root is better, than none at all. > > > I also thought of creating an even more minimal base policy, but I am not > > sure what I should remove from there, without breaking anything (I've > > seen class, inherit, constrain, sid, portcon, fs_xattr,... I think these > > are critical for selinux policy work, aren't they?) Would a more minimal > > policy make selinux work faster? > > The flask definitions (classes, initial SIDs, access vectors) shouldn't > be disturbed, as they are generated into definitions that are built into > the kernel. The fs_use definitions are fundamental and shouldn't be > modified except possibly to add new ones if appropriate for some > filesystem type that you are using. I won't touch them. > Constraints do slow down processing > of the security server computation, but most security decisions are > provided by the AVC after the first such computation, so it isn't really > critical, and the constraints do provide important restrictions. So I'll leave these ones alone too. > Object > context definitions like portcon, netifcon, etc. can be omitted if you > aren't truly using the SELinux network access controls. Primarily, you > just want to minimize the TE rules for memory efficiency. Ok, I'll do this as a final optimization step. > > > Since all the programs that need access to the socket are running already > > (we are generating policies on-the-fly), we can ask the user which > > programs he wants to give access to the socket, and create a policy for > > that. Maybe creating an attribute, and applying that attribute to those > > programs' types, and create a "neverallow ~myattribute" rule for the > > socket access. > > neverallow rules don't grant access; they just specify invariants that > should be checked when policy is compiled (or in the case of modules, > when policy is linked and expanded to kernel policy). I intend to use neverallow to catch policy generation bugs, and ...policy creating logic errors. Also will it stop somebody from loading a policy module that overrides my restrictions? > > > Hmmm...there used to be a clone statement in the language, but it was > ultimately dropped because the semantics were ambiguous and what you > usually want is not truly complete equivalence, just structural > parallel. e.g. for the new type, you don't want to allow it access to > private/derived types of the old type - you want to allow it to access > its own private/derived types. And you don't necessarily want to allow > the same relationships with ancestors and descendants. Consider this scenario: - there is a type: original_exec_t, that transitions to original_t domain; and 10 programs are labeled with it - files created by original_t can be written by another_t - I want to create a rule for only 2 programs out of those, so I create a new type: sub_original_exec_t, sub_original_t and apply this label to these 2 programs. (and I'll create skfilter rules for these labels). I want to keep the allowed interactions between the 10 programs in original_t, so I'll have to give programs that are now sub_original_t, the same right they would have had if they stayed original_t. And I also want to be give another_t write access to files created by sub_original_t (creating files that have the same label as original_t would have gave them should he enough?) Is this what you referred to as structural equivalence? But you are right, if somebody creates descendant types he has to consider which type he actually wants original_t, or sub_original_t . How can I create a type that is structurally equivalent? (read all rules associated with that type from the binary policy, and generate allow/transition/etc. rules based on them?) Thanks in advance, Edwin -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with the words "unsubscribe selinux" without quotes as the message.