summaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorPaul Moore <paul@paul-moore.com>2016-04-04 14:14:42 -0400
committerPaul Moore <paul@paul-moore.com>2016-04-19 16:37:07 -0400
commit20cdef8d57591ec8674f65ccfe555aca5fd10b64 (patch)
tree1c7acbf2540014316925c437a34f2c54c178ae40 /security
parent2c97165befb487c0dc8b25d39f457d0d91d22a6f (diff)
selinux: delay inode label lookup as long as possible
Since looking up an inode's label can result in revalidation, delay the lookup as long as possible to limit the performance impact. Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'security')
-rw-r--r--security/selinux/hooks.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index f8ecc0a3c0fa..b09aad7ad423 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1790,7 +1790,6 @@ static int selinux_determine_inode_label(struct inode *dir,
1790 u32 *_new_isid) 1790 u32 *_new_isid)
1791{ 1791{
1792 const struct superblock_security_struct *sbsec = dir->i_sb->s_security; 1792 const struct superblock_security_struct *sbsec = dir->i_sb->s_security;
1793 const struct inode_security_struct *dsec = inode_security(dir);
1794 const struct task_security_struct *tsec = current_security(); 1793 const struct task_security_struct *tsec = current_security();
1795 1794
1796 if ((sbsec->flags & SE_SBINITIALIZED) && 1795 if ((sbsec->flags & SE_SBINITIALIZED) &&
@@ -1800,6 +1799,7 @@ static int selinux_determine_inode_label(struct inode *dir,
1800 tsec->create_sid) { 1799 tsec->create_sid) {
1801 *_new_isid = tsec->create_sid; 1800 *_new_isid = tsec->create_sid;
1802 } else { 1801 } else {
1802 const struct inode_security_struct *dsec = inode_security(dir);
1803 return security_transition_sid(tsec->sid, dsec->sid, tclass, 1803 return security_transition_sid(tsec->sid, dsec->sid, tclass,
1804 name, _new_isid); 1804 name, _new_isid);
1805 } 1805 }
@@ -2084,7 +2084,7 @@ static int selinux_binder_transfer_file(struct task_struct *from,
2084 u32 sid = task_sid(to); 2084 u32 sid = task_sid(to);
2085 struct file_security_struct *fsec = file->f_security; 2085 struct file_security_struct *fsec = file->f_security;
2086 struct dentry *dentry = file->f_path.dentry; 2086 struct dentry *dentry = file->f_path.dentry;
2087 struct inode_security_struct *isec = backing_inode_security(dentry); 2087 struct inode_security_struct *isec;
2088 struct common_audit_data ad; 2088 struct common_audit_data ad;
2089 int rc; 2089 int rc;
2090 2090
@@ -2103,6 +2103,7 @@ static int selinux_binder_transfer_file(struct task_struct *from,
2103 if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) 2103 if (unlikely(IS_PRIVATE(d_backing_inode(dentry))))
2104 return 0; 2104 return 0;
2105 2105
2106 isec = backing_inode_security(dentry);
2106 return avc_has_perm(sid, isec->sid, isec->sclass, file_to_av(file), 2107 return avc_has_perm(sid, isec->sid, isec->sclass, file_to_av(file),
2107 &ad); 2108 &ad);
2108} 2109}
@@ -3057,7 +3058,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
3057 const void *value, size_t size, int flags) 3058 const void *value, size_t size, int flags)
3058{ 3059{
3059 struct inode *inode = d_backing_inode(dentry); 3060 struct inode *inode = d_backing_inode(dentry);
3060 struct inode_security_struct *isec = backing_inode_security(dentry); 3061 struct inode_security_struct *isec;
3061 struct superblock_security_struct *sbsec; 3062 struct superblock_security_struct *sbsec;
3062 struct common_audit_data ad; 3063 struct common_audit_data ad;
3063 u32 newsid, sid = current_sid(); 3064 u32 newsid, sid = current_sid();
@@ -3076,6 +3077,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
3076 ad.type = LSM_AUDIT_DATA_DENTRY; 3077 ad.type = LSM_AUDIT_DATA_DENTRY;
3077 ad.u.dentry = dentry; 3078 ad.u.dentry = dentry;
3078 3079
3080 isec = backing_inode_security(dentry);
3079 rc = avc_has_perm(sid, isec->sid, isec->sclass, 3081 rc = avc_has_perm(sid, isec->sid, isec->sclass,
3080 FILE__RELABELFROM, &ad); 3082 FILE__RELABELFROM, &ad);
3081 if (rc) 3083 if (rc)
@@ -3134,7 +3136,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
3134 int flags) 3136 int flags)
3135{ 3137{
3136 struct inode *inode = d_backing_inode(dentry); 3138 struct inode *inode = d_backing_inode(dentry);
3137 struct inode_security_struct *isec = backing_inode_security(dentry); 3139 struct inode_security_struct *isec;
3138 u32 newsid; 3140 u32 newsid;
3139 int rc; 3141 int rc;
3140 3142
@@ -3151,6 +3153,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
3151 return; 3153 return;
3152 } 3154 }
3153 3155
3156 isec = backing_inode_security(dentry);
3154 isec->sclass = inode_mode_to_security_class(inode->i_mode); 3157 isec->sclass = inode_mode_to_security_class(inode->i_mode);
3155 isec->sid = newsid; 3158 isec->sid = newsid;
3156 isec->initialized = LABEL_INITIALIZED; 3159 isec->initialized = LABEL_INITIALIZED;
@@ -3192,7 +3195,7 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void
3192 u32 size; 3195 u32 size;
3193 int error; 3196 int error;
3194 char *context = NULL; 3197 char *context = NULL;
3195 struct inode_security_struct *isec = inode_security(inode); 3198 struct inode_security_struct *isec;
3196 3199
3197 if (strcmp(name, XATTR_SELINUX_SUFFIX)) 3200 if (strcmp(name, XATTR_SELINUX_SUFFIX))
3198 return -EOPNOTSUPP; 3201 return -EOPNOTSUPP;
@@ -3211,6 +3214,7 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void
3211 if (!error) 3214 if (!error)
3212 error = cred_has_capability(current_cred(), CAP_MAC_ADMIN, 3215 error = cred_has_capability(current_cred(), CAP_MAC_ADMIN,
3213 SECURITY_CAP_NOAUDIT); 3216 SECURITY_CAP_NOAUDIT);
3217 isec = inode_security(inode);
3214 if (!error) 3218 if (!error)
3215 error = security_sid_to_context_force(isec->sid, &context, 3219 error = security_sid_to_context_force(isec->sid, &context,
3216 &size); 3220 &size);
@@ -3320,7 +3324,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file,
3320 struct common_audit_data ad; 3324 struct common_audit_data ad;
3321 struct file_security_struct *fsec = file->f_security; 3325 struct file_security_struct *fsec = file->f_security;
3322 struct inode *inode = file_inode(file); 3326 struct inode *inode = file_inode(file);
3323 struct inode_security_struct *isec = inode_security(inode); 3327 struct inode_security_struct *isec;
3324 struct lsm_ioctlop_audit ioctl; 3328 struct lsm_ioctlop_audit ioctl;
3325 u32 ssid = cred_sid(cred); 3329 u32 ssid = cred_sid(cred);
3326 int rc; 3330 int rc;
@@ -3344,6 +3348,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file,
3344 if (unlikely(IS_PRIVATE(inode))) 3348 if (unlikely(IS_PRIVATE(inode)))
3345 return 0; 3349 return 0;
3346 3350
3351 isec = inode_security(inode);
3347 rc = avc_has_extended_perms(ssid, isec->sid, isec->sclass, 3352 rc = avc_has_extended_perms(ssid, isec->sid, isec->sclass,
3348 requested, driver, xperm, &ad); 3353 requested, driver, xperm, &ad);
3349out: 3354out:
@@ -3745,18 +3750,18 @@ static int selinux_kernel_module_from_file(struct file *file)
3745 SYSTEM__MODULE_LOAD, NULL); 3750 SYSTEM__MODULE_LOAD, NULL);
3746 3751
3747 /* finit_module */ 3752 /* finit_module */
3753
3748 ad.type = LSM_AUDIT_DATA_PATH; 3754 ad.type = LSM_AUDIT_DATA_PATH;
3749 ad.u.path = file->f_path; 3755 ad.u.path = file->f_path;
3750 3756
3751 isec = inode_security(file_inode(file));
3752 fsec = file->f_security; 3757 fsec = file->f_security;
3753
3754 if (sid != fsec->sid) { 3758 if (sid != fsec->sid) {
3755 rc = avc_has_perm(sid, fsec->sid, SECCLASS_FD, FD__USE, &ad); 3759 rc = avc_has_perm(sid, fsec->sid, SECCLASS_FD, FD__USE, &ad);
3756 if (rc) 3760 if (rc)
3757 return rc; 3761 return rc;
3758 } 3762 }
3759 3763
3764 isec = inode_security(file_inode(file));
3760 return avc_has_perm(sid, isec->sid, SECCLASS_SYSTEM, 3765 return avc_has_perm(sid, isec->sid, SECCLASS_SYSTEM,
3761 SYSTEM__MODULE_LOAD, &ad); 3766 SYSTEM__MODULE_LOAD, &ad);
3762} 3767}