From 6f3be9f562e3027c77bc4482ccf2cea8600a7f74 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Thu, 24 Dec 2015 11:09:40 -0500 Subject: security: Add hook to invalidate inode security labels Add a hook to invalidate an inode's security label when the cached information becomes invalid. Add the new hook in selinux: set a flag when a security label becomes invalid. Signed-off-by: Andreas Gruenbacher Reviewed-by: James Morris Acked-by: Stephen Smalley Signed-off-by: Paul Moore --- security/selinux/hooks.c | 30 ++++++++++++++++++++---------- security/selinux/include/objsec.h | 6 ++++++ 2 files changed, 26 insertions(+), 10 deletions(-) (limited to 'security/selinux') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 1dc0d79a6a25..ef3bd9d61c38 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -820,7 +820,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, goto out; root_isec->sid = rootcontext_sid; - root_isec->initialized = 1; + root_isec->initialized = LABEL_INITIALIZED; } if (defcontext_sid) { @@ -1308,11 +1308,11 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent unsigned len = 0; int rc = 0; - if (isec->initialized) + if (isec->initialized == LABEL_INITIALIZED) goto out; mutex_lock(&isec->lock); - if (isec->initialized) + if (isec->initialized == LABEL_INITIALIZED) goto out_unlock; sbsec = inode->i_sb->s_security; @@ -1484,7 +1484,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent break; } - isec->initialized = 1; + isec->initialized = LABEL_INITIALIZED; out_unlock: mutex_unlock(&isec->lock); @@ -2790,7 +2790,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, struct inode_security_struct *isec = inode->i_security; isec->sclass = inode_mode_to_security_class(inode->i_mode); isec->sid = newsid; - isec->initialized = 1; + isec->initialized = LABEL_INITIALIZED; } if (!ss_initialized || !(sbsec->flags & SBLABEL_MNT)) @@ -3089,7 +3089,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, isec->sclass = inode_mode_to_security_class(inode->i_mode); isec->sid = newsid; - isec->initialized = 1; + isec->initialized = LABEL_INITIALIZED; return; } @@ -3183,7 +3183,7 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name, isec->sclass = inode_mode_to_security_class(inode->i_mode); isec->sid = newsid; - isec->initialized = 1; + isec->initialized = LABEL_INITIALIZED; return 0; } @@ -3761,7 +3761,7 @@ static void selinux_task_to_inode(struct task_struct *p, u32 sid = task_sid(p); isec->sid = sid; - isec->initialized = 1; + isec->initialized = LABEL_INITIALIZED; } /* Returns error only if unable to parse addresses */ @@ -4092,7 +4092,7 @@ static int selinux_socket_post_create(struct socket *sock, int family, return err; } - isec->initialized = 1; + isec->initialized = LABEL_INITIALIZED; if (sock->sk) { sksec = sock->sk->sk_security; @@ -4283,7 +4283,7 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock) isec = inode_security(SOCK_INODE(sock)); newisec->sclass = isec->sclass; newisec->sid = isec->sid; - newisec->initialized = 1; + newisec->initialized = LABEL_INITIALIZED; return 0; } @@ -5775,6 +5775,15 @@ static void selinux_release_secctx(char *secdata, u32 seclen) kfree(secdata); } +static void selinux_inode_invalidate_secctx(struct inode *inode) +{ + struct inode_security_struct *isec = inode->i_security; + + mutex_lock(&isec->lock); + isec->initialized = LABEL_INVALID; + mutex_unlock(&isec->lock); +} + /* * called with inode->i_mutex locked */ @@ -6006,6 +6015,7 @@ static struct security_hook_list selinux_hooks[] = { LSM_HOOK_INIT(secid_to_secctx, selinux_secid_to_secctx), LSM_HOOK_INIT(secctx_to_secid, selinux_secctx_to_secid), LSM_HOOK_INIT(release_secctx, selinux_release_secctx), + LSM_HOOK_INIT(inode_invalidate_secctx, selinux_inode_invalidate_secctx), LSM_HOOK_INIT(inode_notifysecctx, selinux_inode_notifysecctx), LSM_HOOK_INIT(inode_setsecctx, selinux_inode_setsecctx), LSM_HOOK_INIT(inode_getsecctx, selinux_inode_getsecctx), diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 81fa718d5cb3..a2ae05414ba1 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -37,6 +37,12 @@ struct task_security_struct { u32 sockcreate_sid; /* fscreate SID */ }; +enum label_initialized { + LABEL_MISSING, /* not initialized */ + LABEL_INITIALIZED, /* inizialized */ + LABEL_INVALID /* invalid */ +}; + struct inode_security_struct { struct inode *inode; /* back pointer to inode object */ union { -- cgit