aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2008-10-29 17:06:46 -0400
committerJames Morris <jmorris@namei.org>2008-10-30 11:00:52 -0400
commit8b6a5a37f87a414ef8636e36ec75accb27bb7508 (patch)
tree26ff1dddb3c8727118b24819e83b4b7c500ff595
parent0da939b0058742ad2d8580b7db6b966d0fc72252 (diff)
SELinux: check open perms in dentry_open not inode_permission
Some operations, like searching a directory path or connecting a unix domain socket, make explicit calls into inode_permission. Our choices are to either try to come up with a signature for all of the explicit calls to inode_permission and do not check open on those, or to move the open checks to dentry_open where we know this is always an open operation. This patch moves the checks to dentry_open. Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r--security/selinux/hooks.c59
1 files changed, 30 insertions, 29 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c679ba653e1d..03ff7db2a2ca 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1686,15 +1686,39 @@ static inline u32 file_mask_to_av(int mode, int mask)
1686 return av; 1686 return av;
1687} 1687}
1688 1688
1689/* Convert a Linux file to an access vector. */
1690static inline u32 file_to_av(struct file *file)
1691{
1692 u32 av = 0;
1693
1694 if (file->f_mode & FMODE_READ)
1695 av |= FILE__READ;
1696 if (file->f_mode & FMODE_WRITE) {
1697 if (file->f_flags & O_APPEND)
1698 av |= FILE__APPEND;
1699 else
1700 av |= FILE__WRITE;
1701 }
1702 if (!av) {
1703 /*
1704 * Special file opened with flags 3 for ioctl-only use.
1705 */
1706 av = FILE__IOCTL;
1707 }
1708
1709 return av;
1710}
1711
1689/* 1712/*
1690 * Convert a file mask to an access vector and include the correct open 1713 * Convert a file to an access vector and include the correct open
1691 * open permission. 1714 * open permission.
1692 */ 1715 */
1693static inline u32 open_file_mask_to_av(int mode, int mask) 1716static inline u32 open_file_to_av(struct file *file)
1694{ 1717{
1695 u32 av = file_mask_to_av(mode, mask); 1718 u32 av = file_to_av(file);
1696 1719
1697 if (selinux_policycap_openperm) { 1720 if (selinux_policycap_openperm) {
1721 mode_t mode = file->f_path.dentry->d_inode->i_mode;
1698 /* 1722 /*
1699 * lnk files and socks do not really have an 'open' 1723 * lnk files and socks do not really have an 'open'
1700 */ 1724 */
@@ -1710,34 +1734,11 @@ static inline u32 open_file_mask_to_av(int mode, int mask)
1710 av |= DIR__OPEN; 1734 av |= DIR__OPEN;
1711 else 1735 else
1712 printk(KERN_ERR "SELinux: WARNING: inside %s with " 1736 printk(KERN_ERR "SELinux: WARNING: inside %s with "
1713 "unknown mode:%x\n", __func__, mode); 1737 "unknown mode:%o\n", __func__, mode);
1714 } 1738 }
1715 return av; 1739 return av;
1716} 1740}
1717 1741
1718/* Convert a Linux file to an access vector. */
1719static inline u32 file_to_av(struct file *file)
1720{
1721 u32 av = 0;
1722
1723 if (file->f_mode & FMODE_READ)
1724 av |= FILE__READ;
1725 if (file->f_mode & FMODE_WRITE) {
1726 if (file->f_flags & O_APPEND)
1727 av |= FILE__APPEND;
1728 else
1729 av |= FILE__WRITE;
1730 }
1731 if (!av) {
1732 /*
1733 * Special file opened with flags 3 for ioctl-only use.
1734 */
1735 av = FILE__IOCTL;
1736 }
1737
1738 return av;
1739}
1740
1741/* Hook functions begin here. */ 1742/* Hook functions begin here. */
1742 1743
1743static int selinux_ptrace_may_access(struct task_struct *child, 1744static int selinux_ptrace_may_access(struct task_struct *child,
@@ -2654,7 +2655,7 @@ static int selinux_inode_permission(struct inode *inode, int mask)
2654 } 2655 }
2655 2656
2656 return inode_has_perm(current, inode, 2657 return inode_has_perm(current, inode,
2657 open_file_mask_to_av(inode->i_mode, mask), NULL); 2658 file_mask_to_av(inode->i_mode, mask), NULL);
2658} 2659}
2659 2660
2660static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) 2661static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
@@ -3170,7 +3171,7 @@ static int selinux_dentry_open(struct file *file)
3170 * new inode label or new policy. 3171 * new inode label or new policy.
3171 * This check is not redundant - do not remove. 3172 * This check is not redundant - do not remove.
3172 */ 3173 */
3173 return inode_has_perm(current, inode, file_to_av(file), NULL); 3174 return inode_has_perm(current, inode, open_file_to_av(file), NULL);
3174} 3175}
3175 3176
3176/* task security operations */ 3177/* task security operations */