Investigate some kind of mechanism which allows new classes and perms to be selectively enabled, so that people upgrading their kernels without syncing policy can still use their systems normally.
The SELinux module could look up the classes and permissions it requires/checks upon policy load, auditing any undefined ones, and disable/always allow any checks on classes/permissions that are not defined by the policy. Then kernel upgrade would simply disable checking of new permissions until policy is updated to define them. Class/permission string names for class/permissions used by the module are already compiled into the module for AVC auditing purposes, so we already have a table that we can use (although that table also includes userspace classes/permissions since they aren't properly separated yet). Even nicer would be the ability to dynamically map the class/permission values rather than generating the SELinux headers and compiling them into the module, so that we can add, remove and re-arrange classes and permissions and have the kernel adapt. That would be more involved - we'd need a level of indirection between indices used by the SELinux module and the policy values used by the security server, with a mapping created at policy load time and applied at the AVC/security server interface.
(In reply to comment #1) > Even nicer would be the ability to dynamically map the class/permission values I was thinking about something like this, although it is likely very invasive. As a simple measure, what I was considering was a directory /selinux/features, with each node representing a specific feature which has been added, which can be toggled on and off. The default would always be zero for all, and distros would enable them by default as needed. This would only be for new features.
What I don't like about a /selinux/features/ directory is that it creates a coordination problem for policy loads, already encountered with the compat_net support for toggling secmark off or on. We had to modify libselinux (selinux_mkload_policy) to probe the policy image before loading to see whether it contained the definitions required for secmark, and then to set /selinux/compat_net accordingly after loading the policy. This also was non-atomic, so compat_net and the loaded policy may be briefly inconsistent with one another. Whereas the kernel could just as easily have probed itself during the policy load to see whether the packet class was defined, and then set the compat_net value itself internally.
Are there any more ideas on this? does the compat_net take effect immediately when its written or does it wait for the next (successful) policy load? It seems like it should be the latter, that would get rid of the non-atomicity but there are still race issues, hopefully those would be eliminated with policy. its almost like the policy needs to tell the kernel what it supports when its loaded, not in a one-off way by probing for object classes but in a more explicit way (features map in the binary or something). Granted this is a format change and may be too late. Note, this wouldn't just have to apply to object classes which means the version bumps may be minimized in the future by setting features when they don't the format, only how the format is interpreted.
(In reply to comment #4) > Are there any more ideas on this? Not at this stage > does the compat_net take effect immediately > when its written or does it wait for the next (successful) policy load? Immediately. > It seems > like it should be the latter, that would get rid of the non-atomicity but there > are still race issues, hopefully those would be eliminated with policy. It should only be used during early init when bringing the system up.
compat_net is presently set by libselinux when loading policy (either initial policy load or subsequent reload); it first loads the policy, and if that is successful, it proceeds to set compat_net based on whether the packet class was defined in the policy. A features bitmap in the policy would solve the atomicity problem, but you'd still need some mapping between these abstract features and the actual checks (when they correspond to checks). Whereas if the kernel just probed for the definitions required for the checks, it could automatically determine whether the necessary classes and permissions were defined in the policy and could further potentially map its own internal indices to the policy definitions, avoiding the current tight coupling there. OTOH, class/permission definition doesn't necessarily mean that we want the checking, as with the current packet fiasco (class defined, with allow rules added to domains for specific packet types, but no iptables rules in place to apply those types to the packets, and no allow rules for unlabeled_t packets, so we are enabling compat_net without having everything we need in place, and FC6T1 and rawhide are broken).
(In reply to comment #6) > the current packet > fiasco (class defined, with allow rules added to domains for specific packet > types, but no iptables rules in place to apply those types to the packets, and > no allow rules for unlabeled_t packets, so we are enabling compat_net without > having everything we need in place, and FC6T1 and rawhide are broken). Is this being resolved? Does it need a bz?
Chris has said that he will add unlabeled_t packet access pervasively, as with unlabeled_t association access. So once that is done someone on the RH side just needs to pull in an updated refpolicy. Dan is on vacation, so I don't know whether he can do that presently.
Has there been any resolution on this issue yet? I have functionality (labeled networking/CIPSO) that is waiting on a solution to this "new feature" problem. I don't have any strong opinion on the issue, I would just like to know the preferred solution so that I can move forward with development/testing.
On the point of allowing access when object classes are not defined, can't something like default from oskit be used to address this? From the oskit policy: ############################################################################ # # Define the default behavior for permissions that are not # explicitly specified in the type enforcement tables. # # default [allow|auditallow|auditdeny|notify] [none|all|self] ; # default [allow|auditallow|auditdeny|notify] [none|all|self] exclude class_set ; # # The default for allow may be one of: # 1) 'none' - Deny all permissions. # 2) 'all' - Grant all permission. # 3) 'self' - Grant all permissions within a type, but deny # all permissions between types. # # For auditallow, auditdeny and notify, the defaults mean: # 1) 'none' - Audit/notify no permissions. # 2) 'all' - Audit/notify all permissions. # 3) 'self' - Audit/notify all permissions between types, but no # permissions within a type. default allow self exclude { chr_file blk_file rawip_socket packet_socket node netif }; default auditallow none; default auditdeny all; default notify none; was there something fundamentally wrong with this? It would allow flexibility to either allow or deny unknown object classes and perms (based on the site security goals)
Wow, someone looking at my old oskit code. That just specifies the default values for the access vectors in the absence of an avtab entry, which in modern SELinux have become simplified to fixed values (allow nothing, auditallow nothing, auditdeny everything). It doesn't help when the class is completely undefined (compute_av explicitly checks that first along with the SID lookups) or the class is defined but the particular permission is not (particularly if there was an avtab entry for it, but that particular permission happens to not be included since it wasn't defined at all).
Err, I guess I misunderstood it, maybe we can add something that does what i thought it did :). the avc can know about defined classes and # of defined permissions per class, if the query is outside of those ranges we can have a policy rule that defines the default behavior. That would help the RH crowd that wants no breakage and the security crowd that wants no undefined allowance.
I like this. And the default behavior can be as simple as deny or allow (no self necessary). This way the policy author can decide if undefined classes and perms are default deny or default allow. This can be combined with Steve's idea of the kernel probing for defined classes and perms on load to determine what is and what is not defined in the policy. To me this gets us most of the way, with the exception of handling the case where policy exists but labeling doesn't (i.e. netfilter labeling). I'm not sure how common that case is, though.
removing blocker as clearly this won't be in 5.0
This seems to be met by my unknown classes/perms work for 2.6.24 and pmoore's new capability bitmap which will likely show up in 2.6.25. Closing this BZ as I don't think it is helping anyone (but it does hurt me when I have to see so many open BZ's)