From 296fddf7513c155adbd3a443d12add1f62b5cddb Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Mon, 25 Sep 2006 23:32:00 -0700 Subject: [PATCH] SELinux: eliminate inode_security_set_security inode_security_set_sid is only called by security_inode_init_security, which is called when a new file is being created and needs to have its incore security state initialized and its security xattr set. This helper used to be called in other places in the past, but now only has the one. So this patch rolls inode_security_set_sid directly back into security_inode_init_security. There also is no need to hold the isec->sem while doing this, as the inode is not available to other threads at this point in time. Signed-off-by: Eric Paris Acked-by: Stephen Smalley Acked-by: James Morris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/selinux/hooks.c | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) (limited to 'security/selinux/hooks.c') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5a66c4c09f7a..14a78199ee1f 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1364,25 +1364,6 @@ static inline u32 file_to_av(struct file *file) return av; } -/* Set an inode's SID to a specified value. */ -static int inode_security_set_sid(struct inode *inode, u32 sid) -{ - struct inode_security_struct *isec = inode->i_security; - struct superblock_security_struct *sbsec = inode->i_sb->s_security; - - if (!sbsec->initialized) { - /* Defer initialization to selinux_complete_init. */ - return 0; - } - - down(&isec->sem); - isec->sclass = inode_mode_to_security_class(inode->i_mode); - isec->sid = sid; - isec->initialized = 1; - up(&isec->sem); - return 0; -} - /* Hook functions begin here. */ static int selinux_ptrace(struct task_struct *parent, struct task_struct *child) @@ -2091,7 +2072,13 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, } } - inode_security_set_sid(inode, newsid); + /* Possibly defer initialization to selinux_complete_init. */ + if (sbsec->initialized) { + struct inode_security_struct *isec = inode->i_security; + isec->sclass = inode_mode_to_security_class(inode->i_mode); + isec->sid = newsid; + isec->initialized = 1; + } if (!ss_initialized || sbsec->behavior == SECURITY_FS_USE_MNTPOINT) return -EOPNOTSUPP; -- cgit From 23970741720360de9dd0a4e87fbeb1d5927aa474 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Mon, 25 Sep 2006 23:32:01 -0700 Subject: [PATCH] SELinux: change isec semaphore to a mutex This patch converts the remaining isec->sem into a mutex. Very similar locking is provided as before only in the faster smaller mutex rather than a semaphore. An out_unlock path is introduced rather than the conditional unlocking found in the original code. Signed-off-by: Eric Paris Acked-by: Stephen Smalley Acked-by: James Morris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/selinux/hooks.c | 30 ++++++++++++++---------------- security/selinux/include/objsec.h | 2 +- security/selinux/ss/services.c | 4 ++-- 3 files changed, 17 insertions(+), 19 deletions(-) (limited to 'security/selinux/hooks.c') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 14a78199ee1f..63ad57ab44fc 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -71,6 +71,7 @@ #include #include #include +#include #include "avc.h" #include "objsec.h" @@ -185,7 +186,7 @@ static int inode_alloc_security(struct inode *inode) return -ENOMEM; memset(isec, 0, sizeof(*isec)); - init_MUTEX(&isec->sem); + mutex_init(&isec->lock); INIT_LIST_HEAD(&isec->list); isec->inode = inode; isec->sid = SECINITSID_UNLABELED; @@ -843,15 +844,13 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent char *context = NULL; unsigned len = 0; int rc = 0; - int hold_sem = 0; if (isec->initialized) goto out; - down(&isec->sem); - hold_sem = 1; + mutex_lock(&isec->lock); if (isec->initialized) - goto out; + goto out_unlock; sbsec = inode->i_sb->s_security; if (!sbsec->initialized) { @@ -862,7 +861,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent if (list_empty(&isec->list)) list_add(&isec->list, &sbsec->isec_head); spin_unlock(&sbsec->isec_lock); - goto out; + goto out_unlock; } switch (sbsec->behavior) { @@ -885,7 +884,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent printk(KERN_WARNING "%s: no dentry for dev=%s " "ino=%ld\n", __FUNCTION__, inode->i_sb->s_id, inode->i_ino); - goto out; + goto out_unlock; } len = INITCONTEXTLEN; @@ -893,7 +892,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent if (!context) { rc = -ENOMEM; dput(dentry); - goto out; + goto out_unlock; } rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX, context, len); @@ -903,7 +902,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent NULL, 0); if (rc < 0) { dput(dentry); - goto out; + goto out_unlock; } kfree(context); len = rc; @@ -911,7 +910,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent if (!context) { rc = -ENOMEM; dput(dentry); - goto out; + goto out_unlock; } rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX, @@ -924,7 +923,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent "%d for dev=%s ino=%ld\n", __FUNCTION__, -rc, inode->i_sb->s_id, inode->i_ino); kfree(context); - goto out; + goto out_unlock; } /* Map ENODATA to the default file SID */ sid = sbsec->def_sid; @@ -960,7 +959,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent isec->sclass, &sid); if (rc) - goto out; + goto out_unlock; isec->sid = sid; break; case SECURITY_FS_USE_MNTPOINT: @@ -978,7 +977,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent isec->sclass, &sid); if (rc) - goto out; + goto out_unlock; isec->sid = sid; } } @@ -987,12 +986,11 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent isec->initialized = 1; +out_unlock: + mutex_unlock(&isec->lock); out: if (isec->sclass == SECCLASS_FILE) isec->sclass = inode_mode_to_security_class(inode->i_mode); - - if (hold_sem) - up(&isec->sem); return rc; } diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 0a39bfd1319f..7d5a0289878b 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -44,7 +44,7 @@ struct inode_security_struct { u32 sid; /* SID of this object */ u16 sclass; /* security class of this object */ unsigned char initialized; /* initialization flag */ - struct semaphore sem; + struct mutex lock; unsigned char inherit; /* inherit SID from parent entry */ }; diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 988079f45294..0c219a1b3243 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -2578,7 +2578,7 @@ int selinux_netlbl_inode_permission(struct inode *inode, int mask) sock = SOCKET_I(inode); isec = inode->i_security; sksec = sock->sk->sk_security; - down(&isec->sem); + mutex_lock(&isec->lock); if (unlikely(sksec->nlbl_state == NLBL_REQUIRE && (mask & (MAY_WRITE | MAY_APPEND)))) { lock_sock(sock->sk); @@ -2586,7 +2586,7 @@ int selinux_netlbl_inode_permission(struct inode *inode, int mask) release_sock(sock->sk); } else rc = 0; - up(&isec->sem); + mutex_unlock(&isec->lock); return rc; } -- cgit From bc7e982b84aceef0a040c88ff659eb5c83818f72 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Mon, 25 Sep 2006 23:32:02 -0700 Subject: [PATCH] SELinux: convert sbsec semaphore to a mutex This patch converts the semaphore in the superblock security struct to a mutex. No locking changes or other code changes are done. Signed-off-by: Eric Paris Acked-by: Stephen Smalley Acked-by: James Morris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/selinux/hooks.c | 7 +++---- security/selinux/include/objsec.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'security/selinux/hooks.c') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 63ad57ab44fc..55cec4d6f117 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -51,7 +51,6 @@ #include /* for sysctl_local_port_range[] */ #include /* struct or_callable used in sock_rcv_skb */ #include -#include #include #include #include @@ -243,7 +242,7 @@ static int superblock_alloc_security(struct super_block *sb) if (!sbsec) return -ENOMEM; - init_MUTEX(&sbsec->sem); + mutex_init(&sbsec->lock); INIT_LIST_HEAD(&sbsec->list); INIT_LIST_HEAD(&sbsec->isec_head); spin_lock_init(&sbsec->isec_lock); @@ -595,7 +594,7 @@ static int superblock_doinit(struct super_block *sb, void *data) struct inode *inode = root->d_inode; int rc = 0; - down(&sbsec->sem); + mutex_lock(&sbsec->lock); if (sbsec->initialized) goto out; @@ -690,7 +689,7 @@ next_inode: } spin_unlock(&sbsec->isec_lock); out: - up(&sbsec->sem); + mutex_unlock(&sbsec->lock); return rc; } diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 7d5a0289878b..ef2267fea8bd 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -63,7 +63,7 @@ struct superblock_security_struct { unsigned int behavior; /* labeling behavior */ unsigned char initialized; /* initialization flag */ unsigned char proc; /* proc fs */ - struct semaphore sem; + struct mutex lock; struct list_head isec_head; spinlock_t isec_lock; }; -- cgit From b20c8122a3204496fca8b5343c93b60fe11dad04 Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Mon, 25 Sep 2006 23:32:03 -0700 Subject: [PATCH] selinux: fix tty locking Take tty_mutex when accessing ->signal->tty in selinux code. Noted by Alan Cox. Longer term, we are looking at refactoring the code to provide better encapsulation of the tty layer, but this is a simple fix that addresses the immediate bug. Signed-off-by: Stephen Smalley Acked-by: Alan Cox Acked-by: James Morris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/selinux/hooks.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'security/selinux/hooks.c') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 55cec4d6f117..e4d81a42fca4 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1689,10 +1689,12 @@ static inline void flush_unauthorized_files(struct files_struct * files) { struct avc_audit_data ad; struct file *file, *devnull = NULL; - struct tty_struct *tty = current->signal->tty; + struct tty_struct *tty; struct fdtable *fdt; long j = -1; + mutex_lock(&tty_mutex); + tty = current->signal->tty; if (tty) { file_list_lock(); file = list_entry(tty->tty_files.next, typeof(*file), f_u.fu_list); @@ -1712,6 +1714,7 @@ static inline void flush_unauthorized_files(struct files_struct * files) } file_list_unlock(); } + mutex_unlock(&tty_mutex); /* Revalidate access to inherited open files. */ -- cgit