On Thu, Sep 26, 2024 at 1:16 PM Stephen Smalley <stephen.smalley.work@xxxxxxxxx> wrote: > > On Thu, Sep 26, 2024 at 9:14 AM Stephen Smalley > <stephen.smalley.work@xxxxxxxxx> wrote: > > As I've been converting the permission checks to use namespace-aware > > helpers, I've noted policy capabilities (as in network_peer_controls, > > open_perms, extended_socket_class, always_check_network, etc) as a > > case that isn't cleanly handled by my current approach. At present, > > the hook functions are just checking the value of the policy > > capability in the current SELinux namespace to decide which branch of > > the hook function to follow, and then within whichever branch is > > selected, each permission check that is converted to using > > namespace-aware helpers is checking permissions against the current > > and all ancestor namespaces. > > > > So for example, if the current namespace enables open permission, then > > it will check open permission against the current namespace and all > > ancestors, irrespective of whether the ancestor enabled that > > capability or not. Similarly, if the current namespace disables open > > permission, then it will NOT check open permission against any > > namespaces, even if the ancestors enabled it. > > > > Lifting the logic to iterate through all of the namespaces up into > > each hook function is possible but rather painful. That said, it may > > be unavoidable if we want to support different policy capability > > settings between child namespaces and their ancestors, or prevent > > child namespaces from effectively disabling certain checks by > > disabling those capabilities. > > > > If I were to go down that route, then I would also need to resolve how > > to handle the non-permission checking logic in each hook across > > multiple namespaces, e.g. labeling logic. Currently it is just > > assigning SIDs/contexts to objects based on the current namespace, > > then checking permissions against all namespaces with that > > SID/context. But if each hook function has its body wrapped with the > > same loop that currently exists inside the namespace-aware permission > > checking functions to iterate through the namespaces, then we would > > actually end up with multiple SIDs/contexts computed and need to > > decide which one to use (or special case that part of the body to skip > > doing so for anything but the first/current namespace). > > > > Thoughts? > > On 2nd thought, for hooks that don't depend on policy capabilities, I > think the current approach is fine, and works for the majority of the > hooks. > > For the subset of hooks that depend on policy capabilities, I will > lift the logic where needed to ensure that we apply the right checks > in each namespace based on that namespace's enabled policy > capabilities. > > Labeling logic will still be based on the current SELinux namespace at > the point where the kernel object is first created/instantiated, but > permissions to that label will be checked in the current and ancestor > namespaces. There are some potential gotchas there, e.g. a child > namespace could load a policy that labels all objects it > creates/instantiates with a context to which it has access, even > overriding file xattrs by specifying something other than fs_use_xattr > in its policy for the filesystem type. > > Some of the policy capabilities have effects other than changing which > permissions are checked, e.g. extended_socket_class alters what > security class is set in the security blob and later used in > permission checks, so if a socket is created with that disabled in one > namespace and accessed in another namespace, the permission checks > might not be on the "correct" security class for the other namespace. > Other policy capabilities affect labeling, e.g. cgroup_seclabel, > genfs_seclabel_symlinks, userspace_initial_context, which likewise > could lead to an object created and labeled in one namespace > triggering permission checks against the "wrong" label if accessed in > another namespace. Since an increasing number of the testsuite tests are failing in a child SELinux namespace due to even unconfined_t in the parent namespace not being allowed the requisite permissions in the parent namespace, I've created a modified version of the testsuite policy to allow those permissions to unconfined_t and also disabled the tests that cannot work currently due to the separate network namespace. Those changes are on a branch of my fork of the selinux-testsuite at: https://github.com/stephensmalley/selinux-testsuite/tree/selinuxns With those changes, if I load the test policy into the parent namespace (so that the test domains/types are defined and access is allowed to unconfined_t) and then create a child namespace from an unconfined_t shell and run the testsuite from it, all of the (still-enabled) tests pass. I'll keep amending the test policy on that branch with further changes as I convert additional permission checks to be namespace-aware. Eventually we can figure out if it makes sense to merge these into the main testsuite but that can wait until we're ready to merge the kernel namespace support itself.