diff options
Diffstat (limited to 'security/selinux')
-rw-r--r-- | security/selinux/hooks.c | 10 | ||||
-rw-r--r-- | security/selinux/selinuxfs.c | 118 | ||||
-rw-r--r-- | security/selinux/ss/conditional.c | 4 |
3 files changed, 47 insertions, 85 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 40e071af7783..f8110cfd80ff 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -273,11 +273,6 @@ static int __inode_security_revalidate(struct inode *inode, return 0; } -static void inode_security_revalidate(struct inode *inode) -{ - __inode_security_revalidate(inode, NULL, true); -} - static struct inode_security_struct *inode_security_novalidate(struct inode *inode) { return inode->i_security; @@ -3277,19 +3272,19 @@ static int selinux_file_permission(struct file *file, int mask) { struct inode *inode = file_inode(file); struct file_security_struct *fsec = file->f_security; - struct inode_security_struct *isec = inode_security(inode); + struct inode_security_struct *isec; u32 sid = current_sid(); if (!mask) /* No permission to check. Existence test. */ return 0; + isec = inode_security(inode); if (sid == fsec->sid && fsec->isid == isec->sid && fsec->pseqno == avc_policy_seqno()) /* No change since file_open check. */ return 0; - inode_security_revalidate(inode); return selinux_revalidate_file_permission(file, mask); } @@ -3595,7 +3590,6 @@ static int selinux_file_open(struct file *file, const struct cred *cred) * new inode label or new policy. * This check is not redundant - do not remove. */ - inode_security_revalidate(file_inode(file)); return file_path_has_perm(cred, file, open_file_to_av(file)); } diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 0dc407dac3b9..1b1fd27de632 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -148,23 +148,16 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf, ssize_t length; int new_value; - length = -ENOMEM; if (count >= PAGE_SIZE) - goto out; + return -ENOMEM; /* No partial writes. */ - length = -EINVAL; if (*ppos != 0) - goto out; - - length = -ENOMEM; - page = (char *)get_zeroed_page(GFP_KERNEL); - if (!page) - goto out; + return -EINVAL; - length = -EFAULT; - if (copy_from_user(page, buf, count)) - goto out; + page = memdup_user_nul(buf, count); + if (IS_ERR(page)) + return PTR_ERR(page); length = -EINVAL; if (sscanf(page, "%d", &new_value) != 1) @@ -187,7 +180,7 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf, } length = count; out: - free_page((unsigned long) page); + kfree(page); return length; } #else @@ -276,27 +269,20 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - char *page = NULL; + char *page; ssize_t length; int new_value; - length = -ENOMEM; if (count >= PAGE_SIZE) - goto out; + return -ENOMEM; /* No partial writes. */ - length = -EINVAL; if (*ppos != 0) - goto out; - - length = -ENOMEM; - page = (char *)get_zeroed_page(GFP_KERNEL); - if (!page) - goto out; + return -EINVAL; - length = -EFAULT; - if (copy_from_user(page, buf, count)) - goto out; + page = memdup_user_nul(buf, count); + if (IS_ERR(page)) + return PTR_ERR(page); length = -EINVAL; if (sscanf(page, "%d", &new_value) != 1) @@ -314,7 +300,7 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf, length = count; out: - free_page((unsigned long) page); + kfree(page); return length; } #else @@ -394,9 +380,9 @@ static int sel_open_policy(struct inode *inode, struct file *filp) goto err; if (i_size_read(inode) != security_policydb_len()) { - mutex_lock(&inode->i_mutex); + inode_lock(inode); i_size_write(inode, security_policydb_len()); - mutex_unlock(&inode->i_mutex); + inode_unlock(inode); } rc = security_read_policy(&plm->data, &plm->len); @@ -612,31 +598,24 @@ static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf, static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - char *page = NULL; + char *page; ssize_t length; unsigned int new_value; length = task_has_security(current, SECURITY__SETCHECKREQPROT); if (length) - goto out; + return length; - length = -ENOMEM; if (count >= PAGE_SIZE) - goto out; + return -ENOMEM; /* No partial writes. */ - length = -EINVAL; if (*ppos != 0) - goto out; - - length = -ENOMEM; - page = (char *)get_zeroed_page(GFP_KERNEL); - if (!page) - goto out; + return -EINVAL; - length = -EFAULT; - if (copy_from_user(page, buf, count)) - goto out; + page = memdup_user_nul(buf, count); + if (IS_ERR(page)) + return PTR_ERR(page); length = -EINVAL; if (sscanf(page, "%u", &new_value) != 1) @@ -645,7 +624,7 @@ static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf, selinux_checkreqprot = new_value ? 1 : 0; length = count; out: - free_page((unsigned long) page); + kfree(page); return length; } static const struct file_operations sel_checkreqprot_ops = { @@ -1178,14 +1157,12 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf, if (*ppos != 0) goto out; - length = -ENOMEM; - page = (char *)get_zeroed_page(GFP_KERNEL); - if (!page) - goto out; - - length = -EFAULT; - if (copy_from_user(page, buf, count)) + page = memdup_user_nul(buf, count); + if (IS_ERR(page)) { + length = PTR_ERR(page); + page = NULL; goto out; + } length = -EINVAL; if (sscanf(page, "%d", &new_value) != 1) @@ -1199,7 +1176,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf, out: mutex_unlock(&sel_mutex); - free_page((unsigned long) page); + kfree(page); return length; } @@ -1232,14 +1209,12 @@ static ssize_t sel_commit_bools_write(struct file *filep, if (*ppos != 0) goto out; - length = -ENOMEM; - page = (char *)get_zeroed_page(GFP_KERNEL); - if (!page) - goto out; - - length = -EFAULT; - if (copy_from_user(page, buf, count)) + page = memdup_user_nul(buf, count); + if (IS_ERR(page)) { + length = PTR_ERR(page); + page = NULL; goto out; + } length = -EINVAL; if (sscanf(page, "%d", &new_value) != 1) @@ -1254,7 +1229,7 @@ static ssize_t sel_commit_bools_write(struct file *filep, out: mutex_unlock(&sel_mutex); - free_page((unsigned long) page); + kfree(page); return length; } @@ -1370,31 +1345,24 @@ static ssize_t sel_write_avc_cache_threshold(struct file *file, size_t count, loff_t *ppos) { - char *page = NULL; + char *page; ssize_t ret; int new_value; ret = task_has_security(current, SECURITY__SETSECPARAM); if (ret) - goto out; + return ret; - ret = -ENOMEM; if (count >= PAGE_SIZE) - goto out; + return -ENOMEM; /* No partial writes. */ - ret = -EINVAL; if (*ppos != 0) - goto out; - - ret = -ENOMEM; - page = (char *)get_zeroed_page(GFP_KERNEL); - if (!page) - goto out; + return -EINVAL; - ret = -EFAULT; - if (copy_from_user(page, buf, count)) - goto out; + page = memdup_user_nul(buf, count); + if (IS_ERR(page)) + return PTR_ERR(page); ret = -EINVAL; if (sscanf(page, "%u", &new_value) != 1) @@ -1404,7 +1372,7 @@ static ssize_t sel_write_avc_cache_threshold(struct file *file, ret = count; out: - free_page((unsigned long)page); + kfree(page); return ret; } diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c index 18643bf9894d..456e1a9bcfde 100644 --- a/security/selinux/ss/conditional.c +++ b/security/selinux/ss/conditional.c @@ -638,7 +638,7 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key, { struct avtab_node *node; - if (!ctab || !key || !avd || !xperms) + if (!ctab || !key || !avd) return; for (node = avtab_search_node(ctab, key); node; @@ -657,7 +657,7 @@ void cond_compute_av(struct avtab *ctab, struct avtab_key *key, if ((u16)(AVTAB_AUDITALLOW|AVTAB_ENABLED) == (node->key.specified & (AVTAB_AUDITALLOW|AVTAB_ENABLED))) avd->auditallow |= node->datum.u.data; - if ((node->key.specified & AVTAB_ENABLED) && + if (xperms && (node->key.specified & AVTAB_ENABLED) && (node->key.specified & AVTAB_XPERMS)) services_compute_xperms_drivers(xperms, node); } |