The 'associate' permission in SELinux allows to determine if a file with a
given type can be stored on a particular filesystem. Actually this is
checked at mount time for labels specified with parameters 'context',
'rootcontext' and 'defcontext', that can be applied to inodes depending to
the filesystem labeling behavior, during the creation of a file, directory,
symlink or device and, lastly, when modifying the label of an inode using
the setxattr() function.
However the 'associate' permission is not checked in every possible
situation, for example when an inode is initialized with the label fetched
from the SELinux's specific extended attribute. This may be useful to
detect offline changes in the inode's label and to take appropriate
actions.
The behavior defined by this patch is to assign to inodes, which label
does not have the 'associate' permission granted for the containing
filesystem's security context, the 'SECINITSID_UNLABELED' security
identifier, as it happens for instance when the security context fetched
from the extended attribute is not valid.
It is important to note the patch implements the check of the 'associate'
permission only for the 'SECURITY_FS_USE_XATTR' filesystem labeling
behavior. This is not required for the 'SECURITY_FS_USE_TASK' and
'SECURITY_FS_USE_TRANS' labeling behaviors, where the label assigned to
inodes depends to the first accessing task. In the remaining cases the
label is already checked at mount time by the function
may_context_mount_inode_relabel().
Signed-off-by: Roberto Sassu <[email protected]>
---
security/selinux/hooks.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 9486f38..ff55e8d 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1170,6 +1170,7 @@ static int inode_doinit_with_dentry(struct inode *inode,
struct dentry *opt_dent
{
struct superblock_security_struct *sbsec = NULL;
struct inode_security_struct *isec = inode->i_security;
+ struct common_audit_data ad;
u32 sid;
struct dentry *dentry;
#define INITCONTEXTLEN 255
@@ -1196,6 +1197,7 @@ static int inode_doinit_with_dentry(struct inode *inode,
struct dentry *opt_dent
goto out_unlock;
}
+ COMMON_AUDIT_DATA_INIT(&ad, FS);
switch (sbsec->behavior) {
case SECURITY_FS_USE_XATTR:
if (!inode->i_op->getxattr) {
@@ -1292,6 +1294,15 @@ static int inode_doinit_with_dentry(struct inode *inode,
struct dentry *opt_dent
rc = 0;
break;
}
+ rc = avc_has_perm(sid, sbsec->sid,
+ SECCLASS_FILESYSTEM,
+ FILESYSTEM__ASSOCIATE, &ad);
+ if (rc) {
+ kfree(context);
+ /* Leave with the unlabeled SID */
+ rc = 0;
+ break;
+ }
}
kfree(context);
isec->sid = sid;
--
1.7.3.2