Message ID | 20180919165248.53090-1-takondra@cisco.com (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
Series | [RFC] selinux: add a fallback to defcontext for native labeling | expand |
On Wed, Sep 19, 2018 at 12:52 PM Taras Kondratiuk <takondra@cisco.com> wrote: > When files on NFSv4 server are not properly labeled (label doesn't match > a policy on a client) they will end up with unlabeled_t type which is > too generic. We would like to be able to set a default context per > mount. 'defcontext' mount option looks like a nice solution, but it > doesn't seem to be fully implemented for native labeling. Default > context is stored, but is never used. > > The patch adds a fallback to a default context if a received context is > invalid. If the inode context is already initialized, then it is left > untouched to preserve a context set locally on a client. > > Signed-off-by: Taras Kondratiuk <takondra@cisco.com> > --- > security/selinux/hooks.c | 25 ++++++++++++++++++++++++- > 1 file changed, 24 insertions(+), 1 deletion(-) The idea seems reasonable to me; if we want to treat labeled NFS like we treat local filesystems we should also support the defcontext mount option. However, I wonder if we are better off generalizing some of the SECURITY_FS_USE_XATTR based code in inode_doinit_with_dentry() such that it can be used both in selinux_inode_notifysecctx() and in inode_doinit_with_dentry(). Or maybe we just need a sbsec->def_sid variant of selinux_inode_setsecurity(). Regardless, the key is the call to security_context_to_sid_default(), the selinux_inode_setsecurity() function only calls security_context_to_sid(). Just in case anyone is wondering, I'm not sure I want to update selinux_inode_setsecurity() to call security_context_to_sid_default(); at least not without more investigation. > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c > index ad9a9b8e9979..f7debe798bf5 100644 > --- a/security/selinux/hooks.c > +++ b/security/selinux/hooks.c > @@ -6598,7 +6598,30 @@ static void selinux_inode_invalidate_secctx(struct inode *inode) > */ > static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) > { > - return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0); > + struct superblock_security_struct *sbsec; > + struct inode_security_struct *isec; > + int rc; > + > + rc = selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0); > + > + /* > + * In case of Native labeling with defcontext mount option fall back > + * to a default SID if received context is invalid. > + */ > + if (rc == -EINVAL) { > + sbsec = inode->i_sb->s_security; > + if (sbsec->behavior == SECURITY_FS_USE_NATIVE && > + sbsec->flags & DEFCONTEXT_MNT) { > + isec = inode->i_security; > + if (!isec->initialized) { > + isec->sclass = inode_mode_to_security_class(inode->i_mode); > + isec->sid = sbsec->def_sid; > + isec->initialized = 1; > + } > + rc = 0; > + } > + } > + return rc; > } > > /* > -- > 2.10.3.dirty >
On 09/19/2018 12:52 PM, Taras Kondratiuk wrote: > When files on NFSv4 server are not properly labeled (label doesn't match > a policy on a client) they will end up with unlabeled_t type which is > too generic. We would like to be able to set a default context per > mount. 'defcontext' mount option looks like a nice solution, but it > doesn't seem to be fully implemented for native labeling. Default > context is stored, but is never used. > > The patch adds a fallback to a default context if a received context is > invalid. If the inode context is already initialized, then it is left > untouched to preserve a context set locally on a client. Can you explain the use case further? Why are you exporting a filesystem with security labeling enabled to a client that doesn't understand all of the labels used within it? Why wouldn't you just disable NFSv4 security labeling and/or use a regular context= mount to assign a single context to all files in the mount? To be clear, defcontext= doesn't work that way for local/FS_USE_XATTR filesystems. The context specified by it is only used for: 1) files that don't implement the xattr inode operations at all, 2) files that lack a security.selinux xattr, 3) the MLS portion of the context if it was missing (strictly as a legacy compatibility mechanism for RHEL4 which predated the enabling of the MLS field/logic). A file with a security.selinux xattr that is invalid under policy for any reason other than a missing MLS field will be handled as having the unlabeled context. So this would be a divergence in semantics for defcontext= between local/FS_USE_XATTR and NFS/FS_USE_NATIVE filesystems. > > Signed-off-by: Taras Kondratiuk <takondra@cisco.com> > --- > security/selinux/hooks.c | 25 ++++++++++++++++++++++++- > 1 file changed, 24 insertions(+), 1 deletion(-) > > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c > index ad9a9b8e9979..f7debe798bf5 100644 > --- a/security/selinux/hooks.c > +++ b/security/selinux/hooks.c > @@ -6598,7 +6598,30 @@ static void selinux_inode_invalidate_secctx(struct inode *inode) > */ > static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) > { > - return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0); > + struct superblock_security_struct *sbsec; > + struct inode_security_struct *isec; > + int rc; > + > + rc = selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0); In this case, we likely don't gain much by reusing selinux_inode_setsecurity() here and could just inline the relevant portion of it if we were to make this change. Logically they mean different things. > + > + /* > + * In case of Native labeling with defcontext mount option fall back > + * to a default SID if received context is invalid. > + */ > + if (rc == -EINVAL) { > + sbsec = inode->i_sb->s_security; > + if (sbsec->behavior == SECURITY_FS_USE_NATIVE && > + sbsec->flags & DEFCONTEXT_MNT) { > + isec = inode->i_security; > + if (!isec->initialized) { > + isec->sclass = inode_mode_to_security_class(inode->i_mode); > + isec->sid = sbsec->def_sid; > + isec->initialized = 1; > + } > + rc = 0; > + } > + } > + return rc; > } > > /* >
Quoting Stephen Smalley (2018-09-19 12:00:33) > On 09/19/2018 12:52 PM, Taras Kondratiuk wrote: > > When files on NFSv4 server are not properly labeled (label doesn't match > > a policy on a client) they will end up with unlabeled_t type which is > > too generic. We would like to be able to set a default context per > > mount. 'defcontext' mount option looks like a nice solution, but it > > doesn't seem to be fully implemented for native labeling. Default > > context is stored, but is never used. > > > > The patch adds a fallback to a default context if a received context is > > invalid. If the inode context is already initialized, then it is left > > untouched to preserve a context set locally on a client. > > Can you explain the use case further? Why are you exporting a > filesystem with security labeling enabled to a client that doesn't > understand all of the labels used within it? Why wouldn't you just > disable NFSv4 security labeling and/or use a regular context= mount to > assign a single context to all files in the mount? Client and server are two embedded devices. They are part of a bigger modular system and normally run the same SW version, so they understand each others NFSv4 SELinux labels. But during migration from one SW version to another a client and a server may run different versions for some time. The immediate issue I'm trying to address is a migration between releases with and without SELinux policy. A client (with policy) gets initial SID labels from a server (without policy). Those labels are considered invalid, so files remain unlabeled. This also causes lots of errors from nfs_setsecurity() in dmesg. Using 'context=' at mount point level is an option, but in a normal case when both sides have a policy we need more granular labels. It is possible to detect a case when a server doesn't have a policy and remount with 'context=', but this special case handling looks a bit ugly. Having something like 'defcontext' whould allow to avoid this special case and unconditionally assign default context to the mountpoint. 'defcontext' may also help during migration between SELinux-enabled releases if a new release introduces labels that are not recognized by older release. In this case they can also fallback to defcontext. > > To be clear, defcontext= doesn't work that way for local/FS_USE_XATTR > filesystems. The context specified by it is only used for: > 1) files that don't implement the xattr inode operations at all, > 2) files that lack a security.selinux xattr, > 3) the MLS portion of the context if it was missing (strictly as a > legacy compatibility mechanism for RHEL4 which predated the enabling of > the MLS field/logic). > > A file with a security.selinux xattr that is invalid under policy for > any reason other than a missing MLS field will be handled as having the > unlabeled context. inode_doinit_with_dentry() invokes security_context_to_sid_default() that invokes security_context_to_sid_core() with 'force' flag. Won't sidtab_context_to_sid() in this case allocate a new SID for the invalid xattr context instead of leaving it unlabeled? > > So this would be a divergence in semantics for defcontext= between > local/FS_USE_XATTR and NFS/FS_USE_NATIVE filesystems. Yeah, I also didn't like this semantics mismatch. But from another point defcontext allows to assign a context to files that would otherwise be unlabeled. Something similar I'd like to achive for NFS. > > > > > Signed-off-by: Taras Kondratiuk <takondra@cisco.com> > > --- > > security/selinux/hooks.c | 25 ++++++++++++++++++++++++- > > 1 file changed, 24 insertions(+), 1 deletion(-) > > > > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c > > index ad9a9b8e9979..f7debe798bf5 100644 > > --- a/security/selinux/hooks.c > > +++ b/security/selinux/hooks.c > > @@ -6598,7 +6598,30 @@ static void selinux_inode_invalidate_secctx(struct inode *inode) > > */ > > static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) > > { > > - return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0); > > + struct superblock_security_struct *sbsec; > > + struct inode_security_struct *isec; > > + int rc; > > + > > + rc = selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0); > > In this case, we likely don't gain much by reusing > selinux_inode_setsecurity() here and could just inline the relevant > portion of it if we were to make this change. Logically they mean > different things. > > > + > > + /* > > + * In case of Native labeling with defcontext mount option fall back > > + * to a default SID if received context is invalid. > > + */ > > + if (rc == -EINVAL) { > > + sbsec = inode->i_sb->s_security; > > + if (sbsec->behavior == SECURITY_FS_USE_NATIVE && > > + sbsec->flags & DEFCONTEXT_MNT) { > > + isec = inode->i_security; > > + if (!isec->initialized) { > > + isec->sclass = inode_mode_to_security_class(inode->i_mode); > > + isec->sid = sbsec->def_sid; > > + isec->initialized = 1; > > + } > > + rc = 0; > > + } > > + } > > + return rc; > > } > > > > /* > > >
On 09/19/2018 10:41 PM, Taras Kondratiuk wrote: > Quoting Stephen Smalley (2018-09-19 12:00:33) >> On 09/19/2018 12:52 PM, Taras Kondratiuk wrote: >>> When files on NFSv4 server are not properly labeled (label doesn't match >>> a policy on a client) they will end up with unlabeled_t type which is >>> too generic. We would like to be able to set a default context per >>> mount. 'defcontext' mount option looks like a nice solution, but it >>> doesn't seem to be fully implemented for native labeling. Default >>> context is stored, but is never used. >>> >>> The patch adds a fallback to a default context if a received context is >>> invalid. If the inode context is already initialized, then it is left >>> untouched to preserve a context set locally on a client. >> >> Can you explain the use case further? Why are you exporting a >> filesystem with security labeling enabled to a client that doesn't >> understand all of the labels used within it? Why wouldn't you just >> disable NFSv4 security labeling and/or use a regular context= mount to >> assign a single context to all files in the mount? > > Client and server are two embedded devices. They are part of a bigger > modular system and normally run the same SW version, so they understand > each others NFSv4 SELinux labels. But during migration from one SW > version to another a client and a server may run different versions for > some time. > > The immediate issue I'm trying to address is a migration between > releases with and without SELinux policy. A client (with policy) gets > initial SID labels from a server (without policy). Those labels are > considered invalid, so files remain unlabeled. This also causes lots of > errors from nfs_setsecurity() in dmesg. Why are you enabling SELinux on the server without loading a policy? Are you concerned about denials on the server? For that, you could always run it permissive until you are confident you have a working policy. Why are you enabling security_label in exports before you have a policy loaded? It doesn't appear that will ever work, since nfsd asks the security module for the labels, not the local filesystem directly. I understand that this doesn't fully address your use case, but it seems like you could avoid this particular situation altogether just by loading a policy (at which point your server can return actual contexts) or by removing security_label from your exports (at which point your server won't try returning contexts and the client will just apply the default for nfs) until you get to the point of loading a policy. > Using 'context=' at mount point level is an option, but in a normal case > when both sides have a policy we need more granular labels. It is > possible to detect a case when a server doesn't have a policy and > remount with 'context=', but this special case handling looks a bit > ugly. Having something like 'defcontext' whould allow to avoid this > special case and unconditionally assign default context to the > mountpoint. > > 'defcontext' may also help during migration between SELinux-enabled > releases if a new release introduces labels that are not recognized by > older release. In this case they can also fallback to defcontext. This is the more interesting case. And what would these defcontext values be? A context that is generally accessible to all domains on the client? Or one that is restricted to only unconfined domains? Would it be fundamentally different from unlabeled? Will it really differ per-mount, and if so, why? > >> >> To be clear, defcontext= doesn't work that way for local/FS_USE_XATTR >> filesystems. The context specified by it is only used for: >> 1) files that don't implement the xattr inode operations at all, >> 2) files that lack a security.selinux xattr, >> 3) the MLS portion of the context if it was missing (strictly as a >> legacy compatibility mechanism for RHEL4 which predated the enabling of >> the MLS field/logic). >> >> A file with a security.selinux xattr that is invalid under policy for >> any reason other than a missing MLS field will be handled as having the >> unlabeled context. > > inode_doinit_with_dentry() invokes security_context_to_sid_default() > that invokes security_context_to_sid_core() with 'force' flag. Won't > sidtab_context_to_sid() in this case allocate a new SID for the invalid > xattr context instead of leaving it unlabeled? It will be treated as having the unlabeled context for access control purposes and that is what getxattr will return to userspace processes unless they have CAP_MAC_ADMIN and SELinux mac_admin permission, but internally SELinux will keep track of the original xattr context value and will later retry to map it upon a policy reload, switching over to using it for access control and getxattr if it becomes valid under a new policy. That support was added to support scenarios where a package manager sets a file context before it has loaded the policy module that defines it, or scenarios where one is generating a filesystem image for another OS/release with different policy. That is likely something you need/want for NFS as well if you want the client to start using the context as soon as it becomes valid upon a policy update/reload and not have to wait for the inode to be evicted. > >> >> So this would be a divergence in semantics for defcontext= between >> local/FS_USE_XATTR and NFS/FS_USE_NATIVE filesystems. > > Yeah, I also didn't like this semantics mismatch. But from another point > defcontext allows to assign a context to files that would otherwise be > unlabeled. Something similar I'd like to achive for NFS. Yes, I can see the appeal of it. I guess the question is whether we can/should do it via defcontext= or via some new option, and if we do it via defcontext=, can/should we change the semantics for local/xattr filesystems to match? Wondering how widely defcontext= is actually used. > >> >>> >>> Signed-off-by: Taras Kondratiuk <takondra@cisco.com> >>> --- >>> security/selinux/hooks.c | 25 ++++++++++++++++++++++++- >>> 1 file changed, 24 insertions(+), 1 deletion(-) >>> >>> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c >>> index ad9a9b8e9979..f7debe798bf5 100644 >>> --- a/security/selinux/hooks.c >>> +++ b/security/selinux/hooks.c >>> @@ -6598,7 +6598,30 @@ static void selinux_inode_invalidate_secctx(struct inode *inode) >>> */ >>> static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) >>> { >>> - return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0); >>> + struct superblock_security_struct *sbsec; >>> + struct inode_security_struct *isec; >>> + int rc; >>> + >>> + rc = selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0); >> >> In this case, we likely don't gain much by reusing >> selinux_inode_setsecurity() here and could just inline the relevant >> portion of it if we were to make this change. Logically they mean >> different things. >> >>> + >>> + /* >>> + * In case of Native labeling with defcontext mount option fall back >>> + * to a default SID if received context is invalid. >>> + */ >>> + if (rc == -EINVAL) { >>> + sbsec = inode->i_sb->s_security; >>> + if (sbsec->behavior == SECURITY_FS_USE_NATIVE && >>> + sbsec->flags & DEFCONTEXT_MNT) { >>> + isec = inode->i_security; >>> + if (!isec->initialized) { >>> + isec->sclass = inode_mode_to_security_class(inode->i_mode); >>> + isec->sid = sbsec->def_sid; >>> + isec->initialized = 1; >>> + } >>> + rc = 0; >>> + } >>> + } >>> + return rc; >>> } >>> >>> /* >>> >>
Quoting Stephen Smalley (2018-09-20 07:49:12) > On 09/19/2018 10:41 PM, Taras Kondratiuk wrote: > > Quoting Stephen Smalley (2018-09-19 12:00:33) > >> On 09/19/2018 12:52 PM, Taras Kondratiuk wrote: > >>> When files on NFSv4 server are not properly labeled (label doesn't match > >>> a policy on a client) they will end up with unlabeled_t type which is > >>> too generic. We would like to be able to set a default context per > >>> mount. 'defcontext' mount option looks like a nice solution, but it > >>> doesn't seem to be fully implemented for native labeling. Default > >>> context is stored, but is never used. > >>> > >>> The patch adds a fallback to a default context if a received context is > >>> invalid. If the inode context is already initialized, then it is left > >>> untouched to preserve a context set locally on a client. > >> > >> Can you explain the use case further? Why are you exporting a > >> filesystem with security labeling enabled to a client that doesn't > >> understand all of the labels used within it? Why wouldn't you just > >> disable NFSv4 security labeling and/or use a regular context= mount to > >> assign a single context to all files in the mount? > > > > Client and server are two embedded devices. They are part of a bigger > > modular system and normally run the same SW version, so they understand > > each others NFSv4 SELinux labels. But during migration from one SW > > version to another a client and a server may run different versions for > > some time. > > > > The immediate issue I'm trying to address is a migration between > > releases with and without SELinux policy. A client (with policy) gets > > initial SID labels from a server (without policy). Those labels are > > considered invalid, so files remain unlabeled. This also causes lots of > > errors from nfs_setsecurity() in dmesg. > > Why are you enabling SELinux on the server without loading a policy? > Are you concerned about denials on the server? For that, you could > always run it permissive until you are confident you have a working policy. > > Why are you enabling security_label in exports before you have a policy > loaded? It doesn't appear that will ever work, since nfsd asks the > security module for the labels, not the local filesystem directly. > > I understand that this doesn't fully address your use case, but it seems > like you could avoid this particular situation altogether just by > loading a policy (at which point your server can return actual contexts) > or by removing security_label from your exports (at which point your > server won't try returning contexts and the client will just apply the > default for nfs) until you get to the point of loading a policy. It wasn't intentional configuration. Server is running v4.4.x kernel that had security labels enabled by default for NFS 4.2. This was a bug: https://bugzilla.redhat.com/show_bug.cgi?id=1406885 Commit that introduced security_label 32ddd944a056 ("nfsd: opt in to labeled nfs per export") appeared in v4.11 only. We hit this bug during migration to newer releases with SELinux, but the older release is already in the field and we need to handle it. > > > Using 'context=' at mount point level is an option, but in a normal case > > when both sides have a policy we need more granular labels. It is > > possible to detect a case when a server doesn't have a policy and > > remount with 'context=', but this special case handling looks a bit > > ugly. Having something like 'defcontext' whould allow to avoid this > > special case and unconditionally assign default context to the > > mountpoint. > > > > 'defcontext' may also help during migration between SELinux-enabled > > releases if a new release introduces labels that are not recognized by > > older release. In this case they can also fallback to defcontext. > > This is the more interesting case. And what would these defcontext > values be? A context that is generally accessible to all domains on the > client? Or one that is restricted to only unconfined domains? Would it > be fundamentally different from unlabeled? Will it really differ > per-mount, and if so, why? Defcontext will be a restricted label. For example a part of confined domains can access an exported flash disk, but they can't access unlabeled_t. In one release the flash may have a coarse labels: u:r:flash_t . u:r:flash_t some.file u:r:flash_t licence.file u:r:flash_secret_t secret_dir In the next release licence.file may get a more granular label (licence_t), but the older release still need to be able to read the file via NFS. With defcontext=u:r:flash_t it will be able to do it. In our case defcontext will usually match a label or export's root directory, so it needs to be set per-mount. > > > > >> > >> To be clear, defcontext= doesn't work that way for local/FS_USE_XATTR > >> filesystems. The context specified by it is only used for: > >> 1) files that don't implement the xattr inode operations at all, > >> 2) files that lack a security.selinux xattr, > >> 3) the MLS portion of the context if it was missing (strictly as a > >> legacy compatibility mechanism for RHEL4 which predated the enabling of > >> the MLS field/logic). > >> > >> A file with a security.selinux xattr that is invalid under policy for > >> any reason other than a missing MLS field will be handled as having the > >> unlabeled context. > > > > inode_doinit_with_dentry() invokes security_context_to_sid_default() > > that invokes security_context_to_sid_core() with 'force' flag. Won't > > sidtab_context_to_sid() in this case allocate a new SID for the invalid > > xattr context instead of leaving it unlabeled? > > It will be treated as having the unlabeled context for access control > purposes and that is what getxattr will return to userspace processes > unless they have CAP_MAC_ADMIN and SELinux mac_admin permission, but > internally SELinux will keep track of the original xattr context value > and will later retry to map it upon a policy reload, switching over to > using it for access control and getxattr if it becomes valid under a new > policy. That support was added to support scenarios where a package > manager sets a file context before it has loaded the policy module that > defines it, or scenarios where one is generating a filesystem image for > another OS/release with different policy. That is likely something you > need/want for NFS as well if you want the client to start using the > context as soon as it becomes valid upon a policy update/reload and not > have to wait for the inode to be evicted. So now handling of invalid labels is different for xattrs (labels are preserved) and native (labels are discarded). Maybe it is worth to align this behavior. It should make introduction of defcontext for native easier. > > > > >> > >> So this would be a divergence in semantics for defcontext= between > >> local/FS_USE_XATTR and NFS/FS_USE_NATIVE filesystems. > > > > Yeah, I also didn't like this semantics mismatch. But from another point > > defcontext allows to assign a context to files that would otherwise be > > unlabeled. Something similar I'd like to achive for NFS. > > Yes, I can see the appeal of it. I guess the question is whether we > can/should do it via defcontext= or via some new option, and if we do it > via defcontext=, can/should we change the semantics for local/xattr > filesystems to match? Wondering how widely defcontext= is actually used. Is the current behavior of defcontext for xattrs intentional or it is a side effect? Honestly it is a bit confusing. Without defcontext really unlabeled files and files with invalid labels are treated as unlabeled. Can a user without MAC_ADMIN even distinguish them? With defcontext only really unlabeled files get default context, but invalid labels still remain unlabeled. IMO it would be more consistent if defcontext cover all "unlabeled" groups. It seems unlikely to me that somebody who currently uses defcontext can somehow rely on mapping invalid labels to unlabeled instead of default context. > > > > >> > >>> > >>> Signed-off-by: Taras Kondratiuk <takondra@cisco.com> > >>> --- > >>> security/selinux/hooks.c | 25 ++++++++++++++++++++++++- > >>> 1 file changed, 24 insertions(+), 1 deletion(-) > >>> > >>> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c > >>> index ad9a9b8e9979..f7debe798bf5 100644 > >>> --- a/security/selinux/hooks.c > >>> +++ b/security/selinux/hooks.c > >>> @@ -6598,7 +6598,30 @@ static void selinux_inode_invalidate_secctx(struct inode *inode) > >>> */ > >>> static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) > >>> { > >>> - return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0); > >>> + struct superblock_security_struct *sbsec; > >>> + struct inode_security_struct *isec; > >>> + int rc; > >>> + > >>> + rc = selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0); > >> > >> In this case, we likely don't gain much by reusing > >> selinux_inode_setsecurity() here and could just inline the relevant > >> portion of it if we were to make this change. Logically they mean > >> different things. > >> > >>> + > >>> + /* > >>> + * In case of Native labeling with defcontext mount option fall back > >>> + * to a default SID if received context is invalid. > >>> + */ > >>> + if (rc == -EINVAL) { > >>> + sbsec = inode->i_sb->s_security; > >>> + if (sbsec->behavior == SECURITY_FS_USE_NATIVE && > >>> + sbsec->flags & DEFCONTEXT_MNT) { > >>> + isec = inode->i_security; > >>> + if (!isec->initialized) { > >>> + isec->sclass = inode_mode_to_security_class(inode->i_mode); > >>> + isec->sid = sbsec->def_sid; > >>> + isec->initialized = 1; > >>> + } > >>> + rc = 0; > >>> + } > >>> + } > >>> + return rc; > >>> } > >>> > >>> /* > >>> > >> >
On 09/20/2018 06:59 PM, Taras Kondratiuk wrote: > Quoting Stephen Smalley (2018-09-20 07:49:12) >> On 09/19/2018 10:41 PM, Taras Kondratiuk wrote: >>> Quoting Stephen Smalley (2018-09-19 12:00:33) >>>> On 09/19/2018 12:52 PM, Taras Kondratiuk wrote: >>>>> When files on NFSv4 server are not properly labeled (label doesn't match >>>>> a policy on a client) they will end up with unlabeled_t type which is >>>>> too generic. We would like to be able to set a default context per >>>>> mount. 'defcontext' mount option looks like a nice solution, but it >>>>> doesn't seem to be fully implemented for native labeling. Default >>>>> context is stored, but is never used. >>>>> >>>>> The patch adds a fallback to a default context if a received context is >>>>> invalid. If the inode context is already initialized, then it is left >>>>> untouched to preserve a context set locally on a client. >>>> >>>> Can you explain the use case further? Why are you exporting a >>>> filesystem with security labeling enabled to a client that doesn't >>>> understand all of the labels used within it? Why wouldn't you just >>>> disable NFSv4 security labeling and/or use a regular context= mount to >>>> assign a single context to all files in the mount? >>> >>> Client and server are two embedded devices. They are part of a bigger >>> modular system and normally run the same SW version, so they understand >>> each others NFSv4 SELinux labels. But during migration from one SW >>> version to another a client and a server may run different versions for >>> some time. >>> >>> The immediate issue I'm trying to address is a migration between >>> releases with and without SELinux policy. A client (with policy) gets >>> initial SID labels from a server (without policy). Those labels are >>> considered invalid, so files remain unlabeled. This also causes lots of >>> errors from nfs_setsecurity() in dmesg. >> >> Why are you enabling SELinux on the server without loading a policy? >> Are you concerned about denials on the server? For that, you could >> always run it permissive until you are confident you have a working policy. >> >> Why are you enabling security_label in exports before you have a policy >> loaded? It doesn't appear that will ever work, since nfsd asks the >> security module for the labels, not the local filesystem directly. >> >> I understand that this doesn't fully address your use case, but it seems >> like you could avoid this particular situation altogether just by >> loading a policy (at which point your server can return actual contexts) >> or by removing security_label from your exports (at which point your >> server won't try returning contexts and the client will just apply the >> default for nfs) until you get to the point of loading a policy. > > It wasn't intentional configuration. Server is running v4.4.x kernel > that had security labels enabled by default for NFS 4.2. This was a bug: > https://bugzilla.redhat.com/show_bug.cgi?id=1406885 > Commit that introduced security_label 32ddd944a056 ("nfsd: opt in to > labeled nfs per export") appeared in v4.11 only. > > We hit this bug during migration to newer releases with SELinux, but the > older release is already in the field and we need to handle it. Ok, I understand the kernel bug, but not why your servers are in a state where SELinux is enabled but no policy is loaded. That is not a well-tested code path aside from early system initialization prior to first policy load by systemd/init. You would be better off either disabling SELinux on the servers entirely (thereby automatically disabling NFSv4.2 security labeling) or installing/loading a policy on the servers (thereby enabling them to produce valid security labels for the client at least to the extent that they agree on policy). If you are concerned about denials on the server, then you could always leave the servers permissive initially and collect audit logs until you are confident your policy is adequate. >> >>> >>>> >>>> To be clear, defcontext= doesn't work that way for local/FS_USE_XATTR >>>> filesystems. The context specified by it is only used for: >>>> 1) files that don't implement the xattr inode operations at all, >>>> 2) files that lack a security.selinux xattr, >>>> 3) the MLS portion of the context if it was missing (strictly as a >>>> legacy compatibility mechanism for RHEL4 which predated the enabling of >>>> the MLS field/logic). >>>> >>>> A file with a security.selinux xattr that is invalid under policy for >>>> any reason other than a missing MLS field will be handled as having the >>>> unlabeled context. >>> >>> inode_doinit_with_dentry() invokes security_context_to_sid_default() >>> that invokes security_context_to_sid_core() with 'force' flag. Won't >>> sidtab_context_to_sid() in this case allocate a new SID for the invalid >>> xattr context instead of leaving it unlabeled? >> >> It will be treated as having the unlabeled context for access control >> purposes and that is what getxattr will return to userspace processes >> unless they have CAP_MAC_ADMIN and SELinux mac_admin permission, but >> internally SELinux will keep track of the original xattr context value >> and will later retry to map it upon a policy reload, switching over to >> using it for access control and getxattr if it becomes valid under a new >> policy. That support was added to support scenarios where a package >> manager sets a file context before it has loaded the policy module that >> defines it, or scenarios where one is generating a filesystem image for >> another OS/release with different policy. That is likely something you >> need/want for NFS as well if you want the client to start using the >> context as soon as it becomes valid upon a policy update/reload and not >> have to wait for the inode to be evicted. > > So now handling of invalid labels is different for xattrs (labels are > preserved) and native (labels are discarded). Maybe it is worth to align > this behavior. It should make introduction of defcontext for native > easier. Perhaps. However, this handling of invalid labels is in conflict with your suggested behavior for defcontext=. If we set the inode sid to the superblock def_sid on an invalid context, then we lose the association to the original context value. The support for deferred mapping of contexts requires allocating a new SID for the invalid context and storing that SID in the inode, so that if the context later becomes valid upon a policy update/reload, the inode SID will refer to the now valid context. To combine the two, we would need security_context_to_sid_core() to save the def_sid in the context structure for invalid contexts, and change sidtab_search_core() to use that value instead of SECINITSID_UNLABELED for invalid SIDs. Then the inode would be treated as having the defcontext for access control and getxattr() w/o CAP_MAC_ADMIN purposes, but a subsequent policy update/reload that makes the context valid would automatically cause subsequent accesses to the inode to start using the original context value for access control and getxattr() purposes. I think that's the behavior you want. >>>> So this would be a divergence in semantics for defcontext= between >>>> local/FS_USE_XATTR and NFS/FS_USE_NATIVE filesystems. >>> >>> Yeah, I also didn't like this semantics mismatch. But from another point >>> defcontext allows to assign a context to files that would otherwise be >>> unlabeled. Something similar I'd like to achive for NFS. >> >> Yes, I can see the appeal of it. I guess the question is whether we >> can/should do it via defcontext= or via some new option, and if we do it >> via defcontext=, can/should we change the semantics for local/xattr >> filesystems to match? Wondering how widely defcontext= is actually used. > > Is the current behavior of defcontext for xattrs intentional or it is a > side effect? Honestly it is a bit confusing. Without defcontext really > unlabeled files and files with invalid labels are treated as unlabeled. > Can a user without MAC_ADMIN even distinguish them? With defcontext only > really unlabeled files get default context, but invalid labels still > remain unlabeled. It was intentional at the time, but the history is somewhat convoluted. The two cases are actually distinguished by different initial SIDs (SECINITSID_FILE vs SECINITSID_UNLABELED) and used to have different types in policy (file_t vs unlabeled_t), but this distinction has been coalesced in modern policies (where file_t is an alias of unlabeled_t). IIRC, the original distinction was to support migration from non-SELinux to SELinux since filesystems were initially unlabeled. defcontext= was originally just a way of specifying per-mount alternatives to the global policy definition of the context for SECINITSID_FILE. > > IMO it would be more consistent if defcontext cover all "unlabeled" > groups. It seems unlikely to me that somebody who currently uses > defcontext can somehow rely on mapping invalid labels to unlabeled > instead of default context. Yes, and that seems more consistent with the current documentation in the mount man page for defcontext=. I'd be inclined to change selinux_inode_notifysecctx() to call security_context_to_sid_default() directly instead of using selinux_inode_setsecurity() and change security_context_to_sid_core() and sidtab_search_core() as suggested above to save and use the def_sid instead of SECINITSID_UNLABELED always (initializing the context def_sid to SECINITSID_UNLABELED as the default). selinux_inode_setsecurity() we should leave unchanged, or if we change it at all, it should be more like the handling in selinux_inode_setxattr(). The notifysecctx hook is invoked by the filesystem to notify the security module of the file's existing security context, so in that case we always want the _default behavior, whereas the setsecurity hook is invoked by the vfs or the filesystem to set the security context of a file to a new value, so in that case we would only use the _force interface if the caller had CAP_MAC_ADMIN. Paul, what say you? NB This would be a user-visible behavior change for mounts specifying defcontext= on xattr filesystems; files with invalid contexts will then show up with the defcontext value instead of the unlabeled context. If that's too risky, then we'd need a flag or something to security_context_to_sid_default() to distinguish the behaviors and only set it when called from selinux_inode_notifysecctx().
Quoting Stephen Smalley (2018-09-21 07:40:58) > On 09/20/2018 06:59 PM, Taras Kondratiuk wrote: > > Quoting Stephen Smalley (2018-09-20 07:49:12) > >> On 09/19/2018 10:41 PM, Taras Kondratiuk wrote: > >>> Quoting Stephen Smalley (2018-09-19 12:00:33) > >>>> On 09/19/2018 12:52 PM, Taras Kondratiuk wrote: > >>>>> When files on NFSv4 server are not properly labeled (label doesn't match > >>>>> a policy on a client) they will end up with unlabeled_t type which is > >>>>> too generic. We would like to be able to set a default context per > >>>>> mount. 'defcontext' mount option looks like a nice solution, but it > >>>>> doesn't seem to be fully implemented for native labeling. Default > >>>>> context is stored, but is never used. > >>>>> > >>>>> The patch adds a fallback to a default context if a received context is > >>>>> invalid. If the inode context is already initialized, then it is left > >>>>> untouched to preserve a context set locally on a client. > >>>> > >>>> Can you explain the use case further? Why are you exporting a > >>>> filesystem with security labeling enabled to a client that doesn't > >>>> understand all of the labels used within it? Why wouldn't you just > >>>> disable NFSv4 security labeling and/or use a regular context= mount to > >>>> assign a single context to all files in the mount? > >>> > >>> Client and server are two embedded devices. They are part of a bigger > >>> modular system and normally run the same SW version, so they understand > >>> each others NFSv4 SELinux labels. But during migration from one SW > >>> version to another a client and a server may run different versions for > >>> some time. > >>> > >>> The immediate issue I'm trying to address is a migration between > >>> releases with and without SELinux policy. A client (with policy) gets > >>> initial SID labels from a server (without policy). Those labels are > >>> considered invalid, so files remain unlabeled. This also causes lots of > >>> errors from nfs_setsecurity() in dmesg. > >> > >> Why are you enabling SELinux on the server without loading a policy? > >> Are you concerned about denials on the server? For that, you could > >> always run it permissive until you are confident you have a working policy. > >> > >> Why are you enabling security_label in exports before you have a policy > >> loaded? It doesn't appear that will ever work, since nfsd asks the > >> security module for the labels, not the local filesystem directly. > >> > >> I understand that this doesn't fully address your use case, but it seems > >> like you could avoid this particular situation altogether just by > >> loading a policy (at which point your server can return actual contexts) > >> or by removing security_label from your exports (at which point your > >> server won't try returning contexts and the client will just apply the > >> default for nfs) until you get to the point of loading a policy. > > > > It wasn't intentional configuration. Server is running v4.4.x kernel > > that had security labels enabled by default for NFS 4.2. This was a bug: > > https://bugzilla.redhat.com/show_bug.cgi?id=1406885 > > Commit that introduced security_label 32ddd944a056 ("nfsd: opt in to > > labeled nfs per export") appeared in v4.11 only. > > > > We hit this bug during migration to newer releases with SELinux, but the > > older release is already in the field and we need to handle it. > > Ok, I understand the kernel bug, but not why your servers are in a state > where SELinux is enabled but no policy is loaded. That is not a > well-tested code path aside from early system initialization prior to > first policy load by systemd/init. You would be better off either > disabling SELinux on the servers entirely (thereby automatically > disabling NFSv4.2 security labeling) or installing/loading a policy on > the servers (thereby enabling them to produce valid security labels for > the client at least to the extent that they agree on policy). If you > are concerned about denials on the server, then you could always leave > the servers permissive initially and collect audit logs until you are > confident your policy is adequate. It wasn't intentional either. The same kernel configuration is used accross several products. We roll out SELinux for products one by one, so some products don't have SELinux policy and /etc/selinux/config yet while SELinux kernel config is enabled. In hindsight we should have explicitly disabled SELinux in /etc/selinux/config for those products. Since it is not a well-tested code I'm wondering shouldn't systemd/init be disabling SELinux if config file or policy is missing? > > >> > >>> > >>>> > >>>> To be clear, defcontext= doesn't work that way for local/FS_USE_XATTR > >>>> filesystems. The context specified by it is only used for: > >>>> 1) files that don't implement the xattr inode operations at all, > >>>> 2) files that lack a security.selinux xattr, > >>>> 3) the MLS portion of the context if it was missing (strictly as a > >>>> legacy compatibility mechanism for RHEL4 which predated the enabling of > >>>> the MLS field/logic). > >>>> > >>>> A file with a security.selinux xattr that is invalid under policy for > >>>> any reason other than a missing MLS field will be handled as having the > >>>> unlabeled context. > >>> > >>> inode_doinit_with_dentry() invokes security_context_to_sid_default() > >>> that invokes security_context_to_sid_core() with 'force' flag. Won't > >>> sidtab_context_to_sid() in this case allocate a new SID for the invalid > >>> xattr context instead of leaving it unlabeled? > >> > >> It will be treated as having the unlabeled context for access control > >> purposes and that is what getxattr will return to userspace processes > >> unless they have CAP_MAC_ADMIN and SELinux mac_admin permission, but > >> internally SELinux will keep track of the original xattr context value > >> and will later retry to map it upon a policy reload, switching over to > >> using it for access control and getxattr if it becomes valid under a new > >> policy. That support was added to support scenarios where a package > >> manager sets a file context before it has loaded the policy module that > >> defines it, or scenarios where one is generating a filesystem image for > >> another OS/release with different policy. That is likely something you > >> need/want for NFS as well if you want the client to start using the > >> context as soon as it becomes valid upon a policy update/reload and not > >> have to wait for the inode to be evicted. > > > > So now handling of invalid labels is different for xattrs (labels are > > preserved) and native (labels are discarded). Maybe it is worth to align > > this behavior. It should make introduction of defcontext for native > > easier. > > Perhaps. However, this handling of invalid labels is in conflict with > your suggested behavior for defcontext=. If we set the inode sid to the > superblock def_sid on an invalid context, then we lose the association > to the original context value. The support for deferred mapping of > contexts requires allocating a new SID for the invalid context and > storing that SID in the inode, so that if the context later becomes > valid upon a policy update/reload, the inode SID will refer to the now > valid context. To combine the two, we would need > security_context_to_sid_core() to save the def_sid in the context > structure for invalid contexts, and change sidtab_search_core() to use > that value instead of SECINITSID_UNLABELED for invalid SIDs. Then the > inode would be treated as having the defcontext for access control and > getxattr() w/o CAP_MAC_ADMIN purposes, but a subsequent policy > update/reload that makes the context valid would automatically cause > subsequent accesses to the inode to start using the original context > value for access control and getxattr() purposes. I think that's the > behavior you want. Right, that's exactly it. > > >>>> So this would be a divergence in semantics for defcontext= between > >>>> local/FS_USE_XATTR and NFS/FS_USE_NATIVE filesystems. > >>> > >>> Yeah, I also didn't like this semantics mismatch. But from another point > >>> defcontext allows to assign a context to files that would otherwise be > >>> unlabeled. Something similar I'd like to achive for NFS. > >> > >> Yes, I can see the appeal of it. I guess the question is whether we > >> can/should do it via defcontext= or via some new option, and if we do it > >> via defcontext=, can/should we change the semantics for local/xattr > >> filesystems to match? Wondering how widely defcontext= is actually used. > > > > Is the current behavior of defcontext for xattrs intentional or it is a > > side effect? Honestly it is a bit confusing. Without defcontext really > > unlabeled files and files with invalid labels are treated as unlabeled. > > Can a user without MAC_ADMIN even distinguish them? With defcontext only > > really unlabeled files get default context, but invalid labels still > > remain unlabeled. > > It was intentional at the time, but the history is somewhat convoluted. > The two cases are actually distinguished by different initial SIDs > (SECINITSID_FILE vs SECINITSID_UNLABELED) and used to have different > types in policy (file_t vs unlabeled_t), but this distinction has been > coalesced in modern policies (where file_t is an alias of unlabeled_t). > IIRC, the original distinction was to support migration from non-SELinux > to SELinux since filesystems were initially unlabeled. defcontext= was > originally just a way of specifying per-mount alternatives to the global > policy definition of the context for SECINITSID_FILE. > > > > > IMO it would be more consistent if defcontext cover all "unlabeled" > > groups. It seems unlikely to me that somebody who currently uses > > defcontext can somehow rely on mapping invalid labels to unlabeled > > instead of default context. > > Yes, and that seems more consistent with the current documentation in > the mount man page for defcontext=. > > I'd be inclined to change selinux_inode_notifysecctx() to call > security_context_to_sid_default() directly instead of using > selinux_inode_setsecurity() and change security_context_to_sid_core() > and sidtab_search_core() as suggested above to save and use the def_sid > instead of SECINITSID_UNLABELED always (initializing the context def_sid > to SECINITSID_UNLABELED as the default). selinux_inode_setsecurity() we > should leave unchanged, or if we change it at all, it should be more > like the handling in selinux_inode_setxattr(). The notifysecctx hook is > invoked by the filesystem to notify the security module of the file's > existing security context, so in that case we always want the _default > behavior, whereas the setsecurity hook is invoked by the vfs or the > filesystem to set the security context of a file to a new value, so in > that case we would only use the _force interface if the caller had > CAP_MAC_ADMIN. > > Paul, what say you? NB This would be a user-visible behavior change for > mounts specifying defcontext= on xattr filesystems; files with invalid > contexts will then show up with the defcontext value instead of the > unlabeled context. If that's too risky, then we'd need a flag or > something to security_context_to_sid_default() to distinguish the > behaviors and only set it when called from selinux_inode_notifysecctx(). Paul, if you are OK with this approach, then I'll prepare a patch.
On Fri, Sep 21, 2018 at 10:39 AM Stephen Smalley <sds@tycho.nsa.gov> wrote: > On 09/20/2018 06:59 PM, Taras Kondratiuk wrote: > > Quoting Stephen Smalley (2018-09-20 07:49:12) > >> On 09/19/2018 10:41 PM, Taras Kondratiuk wrote: > >>> Quoting Stephen Smalley (2018-09-19 12:00:33) > >>>> On 09/19/2018 12:52 PM, Taras Kondratiuk wrote: ... > > IMO it would be more consistent if defcontext cover all "unlabeled" > > groups. It seems unlikely to me that somebody who currently uses > > defcontext can somehow rely on mapping invalid labels to unlabeled > > instead of default context. > > Yes, and that seems more consistent with the current documentation in > the mount man page for defcontext=. > > I'd be inclined to change selinux_inode_notifysecctx() to call > security_context_to_sid_default() directly instead of using > selinux_inode_setsecurity() and change security_context_to_sid_core() > and sidtab_search_core() as suggested above to save and use the def_sid > instead of SECINITSID_UNLABELED always (initializing the context def_sid > to SECINITSID_UNLABELED as the default). selinux_inode_setsecurity() we > should leave unchanged, or if we change it at all, it should be more > like the handling in selinux_inode_setxattr(). The notifysecctx hook is > invoked by the filesystem to notify the security module of the file's > existing security context, so in that case we always want the _default > behavior, whereas the setsecurity hook is invoked by the vfs or the > filesystem to set the security context of a file to a new value, so in > that case we would only use the _force interface if the caller had > CAP_MAC_ADMIN. > > Paul, what say you? NB This would be a user-visible behavior change for > mounts specifying defcontext= on xattr filesystems; files with invalid > contexts will then show up with the defcontext value instead of the > unlabeled context. If that's too risky, then we'd need a flag or > something to security_context_to_sid_default() to distinguish the > behaviors and only set it when called from selinux_inode_notifysecctx(). Visible changes like this are always worrisome, even though I think it is safe to assume that the defcontext option is not widely used. I'd feel much better if this change was opt-in. Which brings about it's own problems. We have the policy capability functionality, but that is likely a poor fit for this as the policy capabilities are usually controlled by the Linux distribution while the mount options are set by the system's administrator when the filesystem is mounted. We could add a toggle somewhere in selinuxfs, but I really dislike that idea, and would prefer to find a different solution if possible. I'm not sure how much flak we would get for introducing a new mount option, but perhaps that is the best way to handle this: defcontext would continue to behave as it does now, but new option X would behave as mentioned in this thread. Thoughts?
Quoting Paul Moore (2018-09-24 20:46:57) > On Fri, Sep 21, 2018 at 10:39 AM Stephen Smalley <sds@tycho.nsa.gov> wrote: > > On 09/20/2018 06:59 PM, Taras Kondratiuk wrote: > > > Quoting Stephen Smalley (2018-09-20 07:49:12) > > >> On 09/19/2018 10:41 PM, Taras Kondratiuk wrote: > > >>> Quoting Stephen Smalley (2018-09-19 12:00:33) > > >>>> On 09/19/2018 12:52 PM, Taras Kondratiuk wrote: > > ... > > > > IMO it would be more consistent if defcontext cover all "unlabeled" > > > groups. It seems unlikely to me that somebody who currently uses > > > defcontext can somehow rely on mapping invalid labels to unlabeled > > > instead of default context. > > > > Yes, and that seems more consistent with the current documentation in > > the mount man page for defcontext=. > > > > I'd be inclined to change selinux_inode_notifysecctx() to call > > security_context_to_sid_default() directly instead of using > > selinux_inode_setsecurity() and change security_context_to_sid_core() > > and sidtab_search_core() as suggested above to save and use the def_sid > > instead of SECINITSID_UNLABELED always (initializing the context def_sid > > to SECINITSID_UNLABELED as the default). selinux_inode_setsecurity() we > > should leave unchanged, or if we change it at all, it should be more > > like the handling in selinux_inode_setxattr(). The notifysecctx hook is > > invoked by the filesystem to notify the security module of the file's > > existing security context, so in that case we always want the _default > > behavior, whereas the setsecurity hook is invoked by the vfs or the > > filesystem to set the security context of a file to a new value, so in > > that case we would only use the _force interface if the caller had > > CAP_MAC_ADMIN. > > > > Paul, what say you? NB This would be a user-visible behavior change for > > mounts specifying defcontext= on xattr filesystems; files with invalid > > contexts will then show up with the defcontext value instead of the > > unlabeled context. If that's too risky, then we'd need a flag or > > something to security_context_to_sid_default() to distinguish the > > behaviors and only set it when called from selinux_inode_notifysecctx(). > > Visible changes like this are always worrisome, even though I think it > is safe to assume that the defcontext option is not widely used. I'd > feel much better if this change was opt-in. > > Which brings about it's own problems. We have the policy capability > functionality, but that is likely a poor fit for this as the policy > capabilities are usually controlled by the Linux distribution while > the mount options are set by the system's administrator when the > filesystem is mounted. We could add a toggle somewhere in selinuxfs, > but I really dislike that idea, and would prefer to find a different > solution if possible. I'm not sure how much flak we would get for > introducing a new mount option, but perhaps that is the best way to > handle this: defcontext would continue to behave as it does now, but > new option X would behave as mentioned in this thread. > > Thoughts? The new option X will also mean "default context", so it will be pretty hard to come up with a different but a sensible name. I'm afraid that having two options with hardly distinguishable semantics will be very confusing. What about a kernel config option that modifies the behavior of defcontext?
On 09/25/2018 01:45 AM, Taras Kondratiuk wrote: > Quoting Paul Moore (2018-09-24 20:46:57) >> On Fri, Sep 21, 2018 at 10:39 AM Stephen Smalley <sds@tycho.nsa.gov> wrote: >>> On 09/20/2018 06:59 PM, Taras Kondratiuk wrote: >>>> Quoting Stephen Smalley (2018-09-20 07:49:12) >>>>> On 09/19/2018 10:41 PM, Taras Kondratiuk wrote: >>>>>> Quoting Stephen Smalley (2018-09-19 12:00:33) >>>>>>> On 09/19/2018 12:52 PM, Taras Kondratiuk wrote: >> >> ... >> >>>> IMO it would be more consistent if defcontext cover all "unlabeled" >>>> groups. It seems unlikely to me that somebody who currently uses >>>> defcontext can somehow rely on mapping invalid labels to unlabeled >>>> instead of default context. >>> >>> Yes, and that seems more consistent with the current documentation in >>> the mount man page for defcontext=. >>> >>> I'd be inclined to change selinux_inode_notifysecctx() to call >>> security_context_to_sid_default() directly instead of using >>> selinux_inode_setsecurity() and change security_context_to_sid_core() >>> and sidtab_search_core() as suggested above to save and use the def_sid >>> instead of SECINITSID_UNLABELED always (initializing the context def_sid >>> to SECINITSID_UNLABELED as the default). selinux_inode_setsecurity() we >>> should leave unchanged, or if we change it at all, it should be more >>> like the handling in selinux_inode_setxattr(). The notifysecctx hook is >>> invoked by the filesystem to notify the security module of the file's >>> existing security context, so in that case we always want the _default >>> behavior, whereas the setsecurity hook is invoked by the vfs or the >>> filesystem to set the security context of a file to a new value, so in >>> that case we would only use the _force interface if the caller had >>> CAP_MAC_ADMIN. >>> >>> Paul, what say you? NB This would be a user-visible behavior change for >>> mounts specifying defcontext= on xattr filesystems; files with invalid >>> contexts will then show up with the defcontext value instead of the >>> unlabeled context. If that's too risky, then we'd need a flag or >>> something to security_context_to_sid_default() to distinguish the >>> behaviors and only set it when called from selinux_inode_notifysecctx(). >> >> Visible changes like this are always worrisome, even though I think it >> is safe to assume that the defcontext option is not widely used. I'd >> feel much better if this change was opt-in. >> >> Which brings about it's own problems. We have the policy capability >> functionality, but that is likely a poor fit for this as the policy >> capabilities are usually controlled by the Linux distribution while >> the mount options are set by the system's administrator when the >> filesystem is mounted. We could add a toggle somewhere in selinuxfs, >> but I really dislike that idea, and would prefer to find a different >> solution if possible. I'm not sure how much flak we would get for >> introducing a new mount option, but perhaps that is the best way to >> handle this: defcontext would continue to behave as it does now, but >> new option X would behave as mentioned in this thread. >> >> Thoughts? > > The new option X will also mean "default context", so it will be pretty > hard to come up with a different but a sensible name. I'm afraid that > having two options with hardly distinguishable semantics will be very > confusing. > > What about a kernel config option that modifies the behavior of > defcontext? First, the existing documentation for defcontext= leaves open the door to the proposed new behavior. From mount(8): "You can set the default security context for unlabeled files using defcontext= option. This overrides the value set for unlabeled files in the policy and requires a filesystem that supports xattr labeling." "Unlabeled files" could just mean files without any xattr, or it could mean all files that either lack an xattr or have an invalid one under the policy, since both sets of files are currently mapped to the unlabeled context. Second, under what conditions would this situation break existing userspace? The admin would have had to mount an xattr filesystem with defcontext= specified, and that filesystem would have to both contain files without any xattrs and files with invalid ones (otherwise how they are treated by the kernel is irrelevant), and the policy would need to distinguish access to files without xattrs vs files with invalid ones. Seems unlikely. Third, the fact that policy maintainers remapped both SECINITSID_FILE (the default value for defcontext) and SECINITSID_UNLABELED (used for invalid contexts) to the unlabeled context (getting rid of file_t as a separate type, aliased to unlabeled_t) long ago suggests that there is no meaningful difference there. I'm inclined to just change the behavior for defcontext= unconditionally and have it apply to both native and xattr labeling. If that's a no-go, then the simplest solution is to just leave defcontext= behavior unchanged for xattr labeling and only implement the new semantics for native labeling. That's just a matter of adding a flag to security_context_to_sid_default() and only setting it when calling from selinux_inode_notifysecctx().
On Tue, Sep 25, 2018 at 1:45 AM Taras Kondratiuk <takondra@cisco.com> wrote: > Quoting Paul Moore (2018-09-24 20:46:57) > > On Fri, Sep 21, 2018 at 10:39 AM Stephen Smalley <sds@tycho.nsa.gov> wrote: > > > On 09/20/2018 06:59 PM, Taras Kondratiuk wrote: > > > > Quoting Stephen Smalley (2018-09-20 07:49:12) > > > >> On 09/19/2018 10:41 PM, Taras Kondratiuk wrote: > > > >>> Quoting Stephen Smalley (2018-09-19 12:00:33) > > > >>>> On 09/19/2018 12:52 PM, Taras Kondratiuk wrote: > > > > ... > > > > > > IMO it would be more consistent if defcontext cover all "unlabeled" > > > > groups. It seems unlikely to me that somebody who currently uses > > > > defcontext can somehow rely on mapping invalid labels to unlabeled > > > > instead of default context. > > > > > > Yes, and that seems more consistent with the current documentation in > > > the mount man page for defcontext=. > > > > > > I'd be inclined to change selinux_inode_notifysecctx() to call > > > security_context_to_sid_default() directly instead of using > > > selinux_inode_setsecurity() and change security_context_to_sid_core() > > > and sidtab_search_core() as suggested above to save and use the def_sid > > > instead of SECINITSID_UNLABELED always (initializing the context def_sid > > > to SECINITSID_UNLABELED as the default). selinux_inode_setsecurity() we > > > should leave unchanged, or if we change it at all, it should be more > > > like the handling in selinux_inode_setxattr(). The notifysecctx hook is > > > invoked by the filesystem to notify the security module of the file's > > > existing security context, so in that case we always want the _default > > > behavior, whereas the setsecurity hook is invoked by the vfs or the > > > filesystem to set the security context of a file to a new value, so in > > > that case we would only use the _force interface if the caller had > > > CAP_MAC_ADMIN. > > > > > > Paul, what say you? NB This would be a user-visible behavior change for > > > mounts specifying defcontext= on xattr filesystems; files with invalid > > > contexts will then show up with the defcontext value instead of the > > > unlabeled context. If that's too risky, then we'd need a flag or > > > something to security_context_to_sid_default() to distinguish the > > > behaviors and only set it when called from selinux_inode_notifysecctx(). > > > > Visible changes like this are always worrisome, even though I think it > > is safe to assume that the defcontext option is not widely used. I'd > > feel much better if this change was opt-in. > > > > Which brings about it's own problems. We have the policy capability > > functionality, but that is likely a poor fit for this as the policy > > capabilities are usually controlled by the Linux distribution while > > the mount options are set by the system's administrator when the > > filesystem is mounted. We could add a toggle somewhere in selinuxfs, > > but I really dislike that idea, and would prefer to find a different > > solution if possible. I'm not sure how much flak we would get for > > introducing a new mount option, but perhaps that is the best way to > > handle this: defcontext would continue to behave as it does now, but > > new option X would behave as mentioned in this thread. > > > > Thoughts? > > The new option X will also mean "default context", so it will be pretty > hard to come up with a different but a sensible name. I'm afraid that > having two options with hardly distinguishable semantics will be very > confusing. > > What about a kernel config option that modifies the behavior of > defcontext? A kernel config option would be going in the wrong direction; that would put it almost completely under the control of the distribution.
On Tue, Sep 25, 2018 at 9:58 AM Stephen Smalley <sds@tycho.nsa.gov> wrote: > On 09/25/2018 01:45 AM, Taras Kondratiuk wrote: > > Quoting Paul Moore (2018-09-24 20:46:57) > >> On Fri, Sep 21, 2018 at 10:39 AM Stephen Smalley <sds@tycho.nsa.gov> wrote: > >>> On 09/20/2018 06:59 PM, Taras Kondratiuk wrote: > >>>> Quoting Stephen Smalley (2018-09-20 07:49:12) > >>>>> On 09/19/2018 10:41 PM, Taras Kondratiuk wrote: > >>>>>> Quoting Stephen Smalley (2018-09-19 12:00:33) > >>>>>>> On 09/19/2018 12:52 PM, Taras Kondratiuk wrote: > >> > >> ... > >> > >>>> IMO it would be more consistent if defcontext cover all "unlabeled" > >>>> groups. It seems unlikely to me that somebody who currently uses > >>>> defcontext can somehow rely on mapping invalid labels to unlabeled > >>>> instead of default context. > >>> > >>> Yes, and that seems more consistent with the current documentation in > >>> the mount man page for defcontext=. > >>> > >>> I'd be inclined to change selinux_inode_notifysecctx() to call > >>> security_context_to_sid_default() directly instead of using > >>> selinux_inode_setsecurity() and change security_context_to_sid_core() > >>> and sidtab_search_core() as suggested above to save and use the def_sid > >>> instead of SECINITSID_UNLABELED always (initializing the context def_sid > >>> to SECINITSID_UNLABELED as the default). selinux_inode_setsecurity() we > >>> should leave unchanged, or if we change it at all, it should be more > >>> like the handling in selinux_inode_setxattr(). The notifysecctx hook is > >>> invoked by the filesystem to notify the security module of the file's > >>> existing security context, so in that case we always want the _default > >>> behavior, whereas the setsecurity hook is invoked by the vfs or the > >>> filesystem to set the security context of a file to a new value, so in > >>> that case we would only use the _force interface if the caller had > >>> CAP_MAC_ADMIN. > >>> > >>> Paul, what say you? NB This would be a user-visible behavior change for > >>> mounts specifying defcontext= on xattr filesystems; files with invalid > >>> contexts will then show up with the defcontext value instead of the > >>> unlabeled context. If that's too risky, then we'd need a flag or > >>> something to security_context_to_sid_default() to distinguish the > >>> behaviors and only set it when called from selinux_inode_notifysecctx(). > >> > >> Visible changes like this are always worrisome, even though I think it > >> is safe to assume that the defcontext option is not widely used. I'd > >> feel much better if this change was opt-in. > >> > >> Which brings about it's own problems. We have the policy capability > >> functionality, but that is likely a poor fit for this as the policy > >> capabilities are usually controlled by the Linux distribution while > >> the mount options are set by the system's administrator when the > >> filesystem is mounted. We could add a toggle somewhere in selinuxfs, > >> but I really dislike that idea, and would prefer to find a different > >> solution if possible. I'm not sure how much flak we would get for > >> introducing a new mount option, but perhaps that is the best way to > >> handle this: defcontext would continue to behave as it does now, but > >> new option X would behave as mentioned in this thread. > >> > >> Thoughts? > > > > The new option X will also mean "default context", so it will be pretty > > hard to come up with a different but a sensible name. I'm afraid that > > having two options with hardly distinguishable semantics will be very > > confusing. > > > > What about a kernel config option that modifies the behavior of > > defcontext? > > First, the existing documentation for defcontext= leaves open the door > to the proposed new behavior. From mount(8): > "You can set the default security context for unlabeled files using > defcontext= option. This overrides the value set for unlabeled files in > the policy and requires a filesystem that supports xattr labeling." > > "Unlabeled files" could just mean files without any xattr, or it could > mean all files that either lack an xattr or have an invalid one under > the policy, since both sets of files are currently mapped to the > unlabeled context. This may be true for the major SELinux policies being shipped by distributions, but can we say this holds true for *all* SELinux policies in use today? > Second, under what conditions would this situation break existing > userspace? The admin would have had to mount an xattr filesystem with > defcontext= specified, and that filesystem would have to both contain > files without any xattrs and files with invalid ones (otherwise how they > are treated by the kernel is irrelevant), and the policy would need to > distinguish access to files without xattrs vs files with invalid ones. > Seems unlikely. I think you answered your own question. Yes, it is unlikely, but I *really* dislike changing visible behavior like this without some explicit action on behalf of the user/admin. We've done it in the past and it has left me uneasy each time. > Third, the fact that policy maintainers remapped both SECINITSID_FILE > (the default value for defcontext) and SECINITSID_UNLABELED (used for > invalid contexts) to the unlabeled context (getting rid of file_t as a > separate type, aliased to unlabeled_t) long ago suggests that there is > no meaningful difference there. Related to the comments above. > I'm inclined to just change the behavior for defcontext= unconditionally > and have it apply to both native and xattr labeling. If that's a no-go, > then the simplest solution is to just leave defcontext= behavior > unchanged for xattr labeling and only implement the new semantics for > native labeling. That's just a matter of adding a flag to > security_context_to_sid_default() and only setting it when calling from > selinux_inode_notifysecctx(). Neither option is very appealing to me, but that doesn't mean I'm saying "no". From a sanity and consistency point of view I think option #1 (change the defcontext behavior) is a better choice, and I tend to favor this consistency even with the understanding that it could result in some unexpected behavior for users. However, if we get complaints, I'm going to revert this without a second thought. So to answer your question Taras, go ahead and prepare a patch so we can take a look. A bit of fair warning that it might get delayed until after the upcoming merge window since we are already at -rc5; I want this to have plenty of time in -next. Thanks guys.
On 09/25/2018 12:03 PM, Paul Moore wrote: > On Tue, Sep 25, 2018 at 9:58 AM Stephen Smalley <sds@tycho.nsa.gov> wrote: >> On 09/25/2018 01:45 AM, Taras Kondratiuk wrote: >>> Quoting Paul Moore (2018-09-24 20:46:57) >>>> On Fri, Sep 21, 2018 at 10:39 AM Stephen Smalley <sds@tycho.nsa.gov> wrote: >>>>> On 09/20/2018 06:59 PM, Taras Kondratiuk wrote: >>>>>> Quoting Stephen Smalley (2018-09-20 07:49:12) >>>>>>> On 09/19/2018 10:41 PM, Taras Kondratiuk wrote: >>>>>>>> Quoting Stephen Smalley (2018-09-19 12:00:33) >>>>>>>>> On 09/19/2018 12:52 PM, Taras Kondratiuk wrote: >>>> >>>> ... >>>> >>>>>> IMO it would be more consistent if defcontext cover all "unlabeled" >>>>>> groups. It seems unlikely to me that somebody who currently uses >>>>>> defcontext can somehow rely on mapping invalid labels to unlabeled >>>>>> instead of default context. >>>>> >>>>> Yes, and that seems more consistent with the current documentation in >>>>> the mount man page for defcontext=. >>>>> >>>>> I'd be inclined to change selinux_inode_notifysecctx() to call >>>>> security_context_to_sid_default() directly instead of using >>>>> selinux_inode_setsecurity() and change security_context_to_sid_core() >>>>> and sidtab_search_core() as suggested above to save and use the def_sid >>>>> instead of SECINITSID_UNLABELED always (initializing the context def_sid >>>>> to SECINITSID_UNLABELED as the default). selinux_inode_setsecurity() we >>>>> should leave unchanged, or if we change it at all, it should be more >>>>> like the handling in selinux_inode_setxattr(). The notifysecctx hook is >>>>> invoked by the filesystem to notify the security module of the file's >>>>> existing security context, so in that case we always want the _default >>>>> behavior, whereas the setsecurity hook is invoked by the vfs or the >>>>> filesystem to set the security context of a file to a new value, so in >>>>> that case we would only use the _force interface if the caller had >>>>> CAP_MAC_ADMIN. >>>>> >>>>> Paul, what say you? NB This would be a user-visible behavior change for >>>>> mounts specifying defcontext= on xattr filesystems; files with invalid >>>>> contexts will then show up with the defcontext value instead of the >>>>> unlabeled context. If that's too risky, then we'd need a flag or >>>>> something to security_context_to_sid_default() to distinguish the >>>>> behaviors and only set it when called from selinux_inode_notifysecctx(). >>>> >>>> Visible changes like this are always worrisome, even though I think it >>>> is safe to assume that the defcontext option is not widely used. I'd >>>> feel much better if this change was opt-in. >>>> >>>> Which brings about it's own problems. We have the policy capability >>>> functionality, but that is likely a poor fit for this as the policy >>>> capabilities are usually controlled by the Linux distribution while >>>> the mount options are set by the system's administrator when the >>>> filesystem is mounted. We could add a toggle somewhere in selinuxfs, >>>> but I really dislike that idea, and would prefer to find a different >>>> solution if possible. I'm not sure how much flak we would get for >>>> introducing a new mount option, but perhaps that is the best way to >>>> handle this: defcontext would continue to behave as it does now, but >>>> new option X would behave as mentioned in this thread. >>>> >>>> Thoughts? >>> >>> The new option X will also mean "default context", so it will be pretty >>> hard to come up with a different but a sensible name. I'm afraid that >>> having two options with hardly distinguishable semantics will be very >>> confusing. >>> >>> What about a kernel config option that modifies the behavior of >>> defcontext? >> >> First, the existing documentation for defcontext= leaves open the door >> to the proposed new behavior. From mount(8): >> "You can set the default security context for unlabeled files using >> defcontext= option. This overrides the value set for unlabeled files in >> the policy and requires a filesystem that supports xattr labeling." >> >> "Unlabeled files" could just mean files without any xattr, or it could >> mean all files that either lack an xattr or have an invalid one under >> the policy, since both sets of files are currently mapped to the >> unlabeled context. > > This may be true for the major SELinux policies being shipped by > distributions, but can we say this holds true for *all* SELinux > policies in use today? > >> Second, under what conditions would this situation break existing >> userspace? The admin would have had to mount an xattr filesystem with >> defcontext= specified, and that filesystem would have to both contain >> files without any xattrs and files with invalid ones (otherwise how they >> are treated by the kernel is irrelevant), and the policy would need to >> distinguish access to files without xattrs vs files with invalid ones. >> Seems unlikely. > > I think you answered your own question. Yes, it is unlikely, but I > *really* dislike changing visible behavior like this without some > explicit action on behalf of the user/admin. We've done it in the > past and it has left me uneasy each time. > >> Third, the fact that policy maintainers remapped both SECINITSID_FILE >> (the default value for defcontext) and SECINITSID_UNLABELED (used for >> invalid contexts) to the unlabeled context (getting rid of file_t as a >> separate type, aliased to unlabeled_t) long ago suggests that there is >> no meaningful difference there. > > Related to the comments above. > >> I'm inclined to just change the behavior for defcontext= unconditionally >> and have it apply to both native and xattr labeling. If that's a no-go, >> then the simplest solution is to just leave defcontext= behavior >> unchanged for xattr labeling and only implement the new semantics for >> native labeling. That's just a matter of adding a flag to >> security_context_to_sid_default() and only setting it when calling from >> selinux_inode_notifysecctx(). > > Neither option is very appealing to me, but that doesn't mean I'm saying "no". > > From a sanity and consistency point of view I think option #1 (change > the defcontext behavior) is a better choice, and I tend to favor this > consistency even with the understanding that it could result in some > unexpected behavior for users. However, if we get complaints, I'm > going to revert this without a second thought. In that case, I'd suggest splitting it into two patches; first one only enables the new behavior for native labeling filesystems (as per the above, via a flag to security_context_to_sid_default), and the second patch drops the flag and does it unconditionally. Then you can always revert the latter without affecting the former. > > So to answer your question Taras, go ahead and prepare a patch so we > can take a look. A bit of fair warning that it might get delayed > until after the upcoming merge window since we are already at -rc5; I > want this to have plenty of time in -next. > > Thanks guys. >
Quoting Stephen Smalley (2018-09-25 09:39:55) > On 09/25/2018 12:03 PM, Paul Moore wrote: > > On Tue, Sep 25, 2018 at 9:58 AM Stephen Smalley <sds@tycho.nsa.gov> wrote: <snip> > >> I'm inclined to just change the behavior for defcontext= unconditionally > >> and have it apply to both native and xattr labeling. If that's a no-go, > >> then the simplest solution is to just leave defcontext= behavior > >> unchanged for xattr labeling and only implement the new semantics for > >> native labeling. That's just a matter of adding a flag to > >> security_context_to_sid_default() and only setting it when calling from > >> selinux_inode_notifysecctx(). > > > > Neither option is very appealing to me, but that doesn't mean I'm saying "no". > > > > From a sanity and consistency point of view I think option #1 (change > > the defcontext behavior) is a better choice, and I tend to favor this > > consistency even with the understanding that it could result in some > > unexpected behavior for users. However, if we get complaints, I'm > > going to revert this without a second thought. > > In that case, I'd suggest splitting it into two patches; first one only > enables the new behavior for native labeling filesystems (as per the > above, via a flag to security_context_to_sid_default), and the second > patch drops the flag and does it unconditionally. Then you can always > revert the latter without affecting the former. > > > > > So to answer your question Taras, go ahead and prepare a patch so we > > can take a look. A bit of fair warning that it might get delayed > > until after the upcoming merge window since we are already at -rc5; I > > want this to have plenty of time in -next. > > > > Thanks guys. Thanks. I'll prepare patches is a few days.
Quoting Stephen Smalley (2018-09-21 07:40:58) > If we set the inode sid to the superblock def_sid on an invalid > context, then we lose the association to the original context value. > The support for deferred mapping of contexts requires allocating a new > SID for the invalid context and storing that SID in the inode, so that > if the context later becomes valid upon a policy update/reload, the > inode SID will refer to the now valid context. > To combine the two, we would need security_context_to_sid_core() to > save the def_sid in the context structure for invalid contexts, and > change sidtab_search_core() to use that value instead of > SECINITSID_UNLABELED for invalid SIDs. Then the inode would be > treated as having the defcontext for access control and getxattr() w/o > CAP_MAC_ADMIN purposes, but a subsequent policy update/reload that > makes the context valid would automatically cause subsequent accesses > to the inode to start using the original context value for access > control and getxattr() purposes. I think that's the behavior you > want. > While implementing the change I've realized that storing default context for sidtab_search_core() in the context structure is not enough to achieve the desired behavior. The same invalid context may exist in two mounts with different 'defcontext', so default context can't be a property of a context structure. One way to address it is to propagate default context to sidtab_search() all the way from inode hooks. But that will be a bit intrusive. Something like avc_has_perm_default() will need to be added. Other way is to check for context validity in inode hooks and provide a default context to avc_has_perm() if the inode's sid is invalid. But this may have performance implication since validity check will be done each time in fast path. Do you see any other options?
On 10/02/2018 02:48 PM, Taras Kondratiuk wrote: > Quoting Stephen Smalley (2018-09-21 07:40:58) >> If we set the inode sid to the superblock def_sid on an invalid >> context, then we lose the association to the original context value. >> The support for deferred mapping of contexts requires allocating a new >> SID for the invalid context and storing that SID in the inode, so that >> if the context later becomes valid upon a policy update/reload, the >> inode SID will refer to the now valid context. >> To combine the two, we would need security_context_to_sid_core() to >> save the def_sid in the context structure for invalid contexts, and >> change sidtab_search_core() to use that value instead of >> SECINITSID_UNLABELED for invalid SIDs. Then the inode would be >> treated as having the defcontext for access control and getxattr() w/o >> CAP_MAC_ADMIN purposes, but a subsequent policy update/reload that >> makes the context valid would automatically cause subsequent accesses >> to the inode to start using the original context value for access >> control and getxattr() purposes. I think that's the behavior you >> want. >> > > While implementing the change I've realized that storing default context > for sidtab_search_core() in the context structure is not enough to > achieve the desired behavior. The same invalid context may exist in two > mounts with different 'defcontext', so default context can't be a > property of a context structure. > > One way to address it is to propagate default context to sidtab_search() all > the way from inode hooks. But that will be a bit intrusive. Something like > avc_has_perm_default() will need to be added. > > Other way is to check for context validity in inode hooks and provide a default > context to avc_has_perm() if the inode's sid is invalid. But this may have > performance implication since validity check will be done each time in fast > path. > > Do you see any other options? I think the original approach is still best. The def_sid can be part of the context structure; you just need to update context_cmp() to compare it (as part of the first return statement) so that the same invalid context in two mounts with different defcontext= values will allocate different SIDs. Likewise context_cpy() needs to copy the def_sid. As a separate matter, you should also modify security_context_to_sid_force() to pass down the sbsec->def_sid so that when userspace with CAP_MAC_ADMIN sets an invalid context on an inode, the default context will be used in the same manner.
Quoting Stephen Smalley (2018-10-02 12:41:54) > On 10/02/2018 02:48 PM, Taras Kondratiuk wrote: > > Quoting Stephen Smalley (2018-09-21 07:40:58) > >> If we set the inode sid to the superblock def_sid on an invalid > >> context, then we lose the association to the original context value. > >> The support for deferred mapping of contexts requires allocating a new > >> SID for the invalid context and storing that SID in the inode, so that > >> if the context later becomes valid upon a policy update/reload, the > >> inode SID will refer to the now valid context. > >> To combine the two, we would need security_context_to_sid_core() to > >> save the def_sid in the context structure for invalid contexts, and > >> change sidtab_search_core() to use that value instead of > >> SECINITSID_UNLABELED for invalid SIDs. Then the inode would be > >> treated as having the defcontext for access control and getxattr() w/o > >> CAP_MAC_ADMIN purposes, but a subsequent policy update/reload that > >> makes the context valid would automatically cause subsequent accesses > >> to the inode to start using the original context value for access > >> control and getxattr() purposes. I think that's the behavior you > >> want. > >> > > > > While implementing the change I've realized that storing default context > > for sidtab_search_core() in the context structure is not enough to > > achieve the desired behavior. The same invalid context may exist in two > > mounts with different 'defcontext', so default context can't be a > > property of a context structure. > > > > One way to address it is to propagate default context to sidtab_search() all > > the way from inode hooks. But that will be a bit intrusive. Something like > > avc_has_perm_default() will need to be added. > > > > Other way is to check for context validity in inode hooks and provide a default > > context to avc_has_perm() if the inode's sid is invalid. But this may have > > performance implication since validity check will be done each time in fast > > path. > > > > Do you see any other options? > > I think the original approach is still best. The def_sid can be part of > the context structure; you just need to update context_cmp() to compare > it (as part of the first return statement) so that the same invalid > context in two mounts with different defcontext= values will allocate > different SIDs. Likewise context_cpy() needs to copy the def_sid. > > As a separate matter, you should also modify > security_context_to_sid_force() to pass down the sbsec->def_sid so that > when userspace with CAP_MAC_ADMIN sets an invalid context on an inode, > the default context will be used in the same manner. Thanks. That's really a better approach.
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index ad9a9b8e9979..f7debe798bf5 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -6598,7 +6598,30 @@ static void selinux_inode_invalidate_secctx(struct inode *inode) */ static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) { - return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0); + struct superblock_security_struct *sbsec; + struct inode_security_struct *isec; + int rc; + + rc = selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0); + + /* + * In case of Native labeling with defcontext mount option fall back + * to a default SID if received context is invalid. + */ + if (rc == -EINVAL) { + sbsec = inode->i_sb->s_security; + if (sbsec->behavior == SECURITY_FS_USE_NATIVE && + sbsec->flags & DEFCONTEXT_MNT) { + isec = inode->i_security; + if (!isec->initialized) { + isec->sclass = inode_mode_to_security_class(inode->i_mode); + isec->sid = sbsec->def_sid; + isec->initialized = 1; + } + rc = 0; + } + } + return rc; } /*
When files on NFSv4 server are not properly labeled (label doesn't match a policy on a client) they will end up with unlabeled_t type which is too generic. We would like to be able to set a default context per mount. 'defcontext' mount option looks like a nice solution, but it doesn't seem to be fully implemented for native labeling. Default context is stored, but is never used. The patch adds a fallback to a default context if a received context is invalid. If the inode context is already initialized, then it is left untouched to preserve a context set locally on a client. Signed-off-by: Taras Kondratiuk <takondra@cisco.com> --- security/selinux/hooks.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-)