Message ID | 20190912133007.27545-1-jlebon@redhat.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
Series | [v2] selinux: allow labeling before policy is loaded | expand |
On Thu, Sep 12, 2019 at 9:30 AM Jonathan Lebon <jlebon@redhat.com> wrote: > Currently, the SELinux LSM prevents one from setting the > `security.selinux` xattr on an inode without a policy first being > loaded. However, this restriction is problematic: it makes it impossible > to have newly created files with the correct label before actually > loading the policy. > > This is relevant in distributions like Fedora, where the policy is > loaded by systemd shortly after pivoting out of the initrd. In such > instances, all files created prior to pivoting will be unlabeled. One > then has to relabel them after pivoting, an operation which inherently > races with other processes trying to access those same files. > > Going further, there are use cases for creating the entire root > filesystem on first boot from the initrd (e.g. Container Linux supports > this today[1], and we'd like to support it in Fedora CoreOS as well[2]). > One can imagine doing this in two ways: at the block device level (e.g. > laying down a disk image), or at the filesystem level. In the former, > labeling can simply be part of the image. But even in the latter > scenario, one still really wants to be able to set the right labels when > populating the new filesystem. > > This patch enables this by changing behaviour in the following two ways: > 1. allow `setxattr` if we're not initialized > 2. don't try to set the in-core inode SID if we're not initialized; > instead leave it as `LABEL_INVALID` so that revalidation may be > attempted at a later time > > Note the first hunk of this patch is mostly the same as a previously > discussed one[3], though it was part of a larger series which wasn't > accepted. > > Co-developed-by: Victor Kamensky <kamensky@cisco.com> > Signed-off-by: Victor Kamensky <kamensky@cisco.com> > Signed-off-by: Jonathan Lebon <jlebon@redhat.com> > > [1] https://coreos.com/os/docs/latest/root-filesystem-placement.html > [2] https://github.com/coreos/fedora-coreos-tracker/issues/94 > [3] https://www.spinics.net/lists/linux-initramfs/msg04593.html > > --- > > v2: > - return early in selinux_inode_setxattr if policy hasn't been loaded > > --- > > security/selinux/hooks.c | 12 ++++++++++++ > 1 file changed, 12 insertions(+) Merged into selinux/next, thanks!
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 94de51628..dbe96c707 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3142,6 +3142,9 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, return dentry_has_perm(current_cred(), dentry, FILE__SETATTR); } + if (!selinux_state.initialized) + return (inode_owner_or_capable(inode) ? 0 : -EPERM); + sbsec = inode->i_sb->s_security; if (!(sbsec->flags & SBLABEL_MNT)) return -EOPNOTSUPP; @@ -3225,6 +3228,15 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, return; } + if (!selinux_state.initialized) { + /* If we haven't even been initialized, then we can't validate + * against a policy, so leave the label as invalid. It may + * resolve to a valid label on the next revalidation try if + * we've since initialized. + */ + return; + } + rc = security_context_to_sid_force(&selinux_state, value, size, &newsid); if (rc) {