aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c66
1 files changed, 37 insertions, 29 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index f85597a4d733..f71de5a64d0c 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1687,15 +1687,39 @@ static inline u32 file_mask_to_av(int mode, int mask)
1687 return av; 1687 return av;
1688} 1688}
1689 1689
1690/* Convert a Linux file to an access vector. */
1691static inline u32 file_to_av(struct file *file)
1692{
1693 u32 av = 0;
1694
1695 if (file->f_mode & FMODE_READ)
1696 av |= FILE__READ;
1697 if (file->f_mode & FMODE_WRITE) {
1698 if (file->f_flags & O_APPEND)
1699 av |= FILE__APPEND;
1700 else
1701 av |= FILE__WRITE;
1702 }
1703 if (!av) {
1704 /*
1705 * Special file opened with flags 3 for ioctl-only use.
1706 */
1707 av = FILE__IOCTL;
1708 }
1709
1710 return av;
1711}
1712
1690/* 1713/*
1691 * Convert a file mask to an access vector and include the correct open 1714 * Convert a file to an access vector and include the correct open
1692 * open permission. 1715 * open permission.
1693 */ 1716 */
1694static inline u32 open_file_mask_to_av(int mode, int mask) 1717static inline u32 open_file_to_av(struct file *file)
1695{ 1718{
1696 u32 av = file_mask_to_av(mode, mask); 1719 u32 av = file_to_av(file);
1697 1720
1698 if (selinux_policycap_openperm) { 1721 if (selinux_policycap_openperm) {
1722 mode_t mode = file->f_path.dentry->d_inode->i_mode;
1699 /* 1723 /*
1700 * lnk files and socks do not really have an 'open' 1724 * lnk files and socks do not really have an 'open'
1701 */ 1725 */
@@ -1711,34 +1735,11 @@ static inline u32 open_file_mask_to_av(int mode, int mask)
1711 av |= DIR__OPEN; 1735 av |= DIR__OPEN;
1712 else 1736 else
1713 printk(KERN_ERR "SELinux: WARNING: inside %s with " 1737 printk(KERN_ERR "SELinux: WARNING: inside %s with "
1714 "unknown mode:%x\n", __func__, mode); 1738 "unknown mode:%o\n", __func__, mode);
1715 } 1739 }
1716 return av; 1740 return av;
1717} 1741}
1718 1742
1719/* Convert a Linux file to an access vector. */
1720static inline u32 file_to_av(struct file *file)
1721{
1722 u32 av = 0;
1723
1724 if (file->f_mode & FMODE_READ)
1725 av |= FILE__READ;
1726 if (file->f_mode & FMODE_WRITE) {
1727 if (file->f_flags & O_APPEND)
1728 av |= FILE__APPEND;
1729 else
1730 av |= FILE__WRITE;
1731 }
1732 if (!av) {
1733 /*
1734 * Special file opened with flags 3 for ioctl-only use.
1735 */
1736 av = FILE__IOCTL;
1737 }
1738
1739 return av;
1740}
1741
1742/* Hook functions begin here. */ 1743/* Hook functions begin here. */
1743 1744
1744static int selinux_ptrace_may_access(struct task_struct *child, 1745static int selinux_ptrace_may_access(struct task_struct *child,
@@ -2269,7 +2270,9 @@ static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm)
2269 struct rlimit *rlim, *initrlim; 2270 struct rlimit *rlim, *initrlim;
2270 struct itimerval itimer; 2271 struct itimerval itimer;
2271 struct bprm_security_struct *bsec; 2272 struct bprm_security_struct *bsec;
2273 struct sighand_struct *psig;
2272 int rc, i; 2274 int rc, i;
2275 unsigned long flags;
2273 2276
2274 tsec = current->security; 2277 tsec = current->security;
2275 bsec = bprm->security; 2278 bsec = bprm->security;
@@ -2330,7 +2333,12 @@ static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm)
2330 2333
2331 /* Wake up the parent if it is waiting so that it can 2334 /* Wake up the parent if it is waiting so that it can
2332 recheck wait permission to the new task SID. */ 2335 recheck wait permission to the new task SID. */
2336 read_lock_irq(&tasklist_lock);
2337 psig = current->parent->sighand;
2338 spin_lock_irqsave(&psig->siglock, flags);
2333 wake_up_interruptible(&current->parent->signal->wait_chldexit); 2339 wake_up_interruptible(&current->parent->signal->wait_chldexit);
2340 spin_unlock_irqrestore(&psig->siglock, flags);
2341 read_unlock_irq(&tasklist_lock);
2334} 2342}
2335 2343
2336/* superblock security operations */ 2344/* superblock security operations */
@@ -2650,7 +2658,7 @@ static int selinux_inode_permission(struct inode *inode, int mask)
2650 } 2658 }
2651 2659
2652 return inode_has_perm(current, inode, 2660 return inode_has_perm(current, inode,
2653 open_file_mask_to_av(inode->i_mode, mask), NULL); 2661 file_mask_to_av(inode->i_mode, mask), NULL);
2654} 2662}
2655 2663
2656static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) 2664static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
@@ -3166,7 +3174,7 @@ static int selinux_dentry_open(struct file *file)
3166 * new inode label or new policy. 3174 * new inode label or new policy.
3167 * This check is not redundant - do not remove. 3175 * This check is not redundant - do not remove.
3168 */ 3176 */
3169 return inode_has_perm(current, inode, file_to_av(file), NULL); 3177 return inode_has_perm(current, inode, open_file_to_av(file), NULL);
3170} 3178}
3171 3179
3172/* task security operations */ 3180/* task security operations */