So one of the features that has been a long time in coming is the ability to replace the unconfined profile. We aren't there yet but it is something I would like to consider for the 3.0 release. To do this we need to make a few decisions, and fix a few things.
So why would you want to replace the unconfined profile? Its a way of providing total system policy without having it compiled into the init ramdisk. So why does apparmor have an unconfined state (profile) and what needs to be done to enable it to be replaced? And just to be explicit, by replaced I mean doing profile replacement on it, not removing it. A bit of history, and where we are at now AppArmor started out as a targeted policy access control system, designed to control accesses of network facing daemons, while leaving the rest of the system to be controlled by standard unix access restrictions (DAC). This early version of AppArmor could not really do a total system policy as profiles could only be attached based on executable names, and early policy load was not possible. The state of the tasks not being confined was variously called unconfined, unconstrained, and a few other things before unconfined was standardized on at some point. Because apparmor was designed to have as little impact on the unconfined parts of the system as possible, it was implemented so that tasks in the unconfined state would exit early from LSM hooks (this is still some what true to this day). With the release of AppArmor 2.3 the unconfined state moved to being a special unconfined profile. This was done to support the new and experimental feature, policy namespaces. Each namespace had its own unconfined profile and unconfined tasks within a given namespace would be labeled with either a profile from the namespace or the special unconfined profile. AppArmor 2.4 saw the addition of pattern matching to profile names, basic caching of precompiled profiles and the AppArmor module being built into the kernel, which allowed for early policy load via the initramfs and the first real ability to do a total system policy. However this required the policy be completely defined and properly compiled into the ram disk which was problematic, especially as the only loader utility was the full apparmor_parser. AppArmor 2.5 saw the addition of name lookup control flags (chroot_relative, namespace, attach_disconnected, ..), the final namespace design and renaming replacement. The namespace lookup control flags allowed policy to be able to handle corner cases that didn't occur often in most daemons but do for system policies, and renaming replacement allowed for profiles with one name to be replaced with profiles with another name (this finally provided for the ability to rename with a new more relavent name, say unconfined with /** or default, ..) AppArmor 2.6 added the ability for profile names and attachment specifications to be defined separately, allowing for profile names to be more meaningful to users. And all of the AppArmor releases since 2.1 have been working on improving the DFA compilation engine so that we could do some interesting things with total system policy and implicit labeling. So to summarize - unconfined is a special profile that provides early exit - AppArmor can provide early policy if it is compiled into the initramdisk and profile globbing is used. - corner cases can be "fixed" with the name lookup flags - profiles can be renamed when they are replaced Why would someone want to replace the unconfined profile instead of providing early policy. Well the biggest reason is that providing early policy is a pita and for how most people use apparmor. Early system startup doesn't really need to have a full policy, replacing the unconfined profile used during early start up is easier, fits the majority of policy needs and it needs minimal extra additions to support it. Renaming replacement etc is already available and has other uses. So what is left to do so we can "replace" the unconfined profile - make a few design decisions - put the unconfined profile on the namespaces profile list - provide a method of marking a profile as immutable (so some unconfined or other profiles can be marked as immutable if needed by the policy) - deal with path lookup performance problems - deal with the corner cases that the path lookup control flags are "fixing" AppArmor 3.0 should finally be able to deal with the remaining issues of path lookup performance and the problem corner cases (disconnected paths, deleted files, ..) by using implicit labeling, shared DFAs, and delegation. Making the unconfined profile available for replacement is trivial, so that is not really a consideration. So what decisions are left to be made? - should the unconfined profile show up in profile listings? - should a profile replacing unconfined be allowed to be called unconfined? That is a profile that replaces unconfined isn't really a special unconfined state any more, should we not allow its replacement to be called unconfined so as to not cause confusion there, or do we allow it to avoid confusion caused by the next point - should replacing the unconfined profile actual replace the profile or just task instance using the profile? That is to say what is the behavior of /foo ux, # does this enter the profile that replaced unconfined or does it enter the unconfined profile, or does it fail same questions for /foo px -> unconfined, and for change_profile ->unconfined, - should there be a way to replace the unconfined profiles in all namespaces? Currently this would be on a namespace by namespace basis. - should a sub-namespace inherit the "unconfined" profile from its parent? Currently namespaces don't inherit profiles but unconfined is special and that might be the right decision for them, nor would it break current semantics in that it could be said that new namespaces inherit their parents unconfined profile (which just can't be replaced currently). -- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor