aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruenba@redhat.com>2015-12-24 11:09:40 -0500
committerPaul Moore <pmoore@redhat.com>2015-12-24 11:09:40 -0500
commit5d226df4edfa0eb1e689e7ac2741cf261ff7cbf1 (patch)
tree3fe85bb21b799df769d9079687c874ba1569a4fa
parent6f3be9f562e3027c77bc4482ccf2cea8600a7f74 (diff)
selinux: Revalidate invalid inode security labels
When fetching an inode's security label, check if it is still valid, and try reloading it if it is not. Reloading will fail when we are in RCU context which doesn't allow sleeping, or when we can't find a dentry for the inode. (Reloading happens via iop->getxattr which takes a dentry parameter.) When reloading fails, continue using the old, invalid label. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Acked-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: Paul Moore <pmoore@redhat.com>
-rw-r--r--security/selinux/hooks.c76
1 files changed, 68 insertions, 8 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index ef3bd9d61c38..34e3351239d8 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -242,11 +242,63 @@ static int inode_alloc_security(struct inode *inode)
242 return 0; 242 return 0;
243} 243}
244 244
245static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
246
247/*
248 * Try reloading inode security labels that have been marked as invalid. The
249 * @may_sleep parameter indicates when sleeping and thus reloading labels is
250 * allowed; when set to false, returns ERR_PTR(-ECHILD) when the label is
251 * invalid. The @opt_dentry parameter should be set to a dentry of the inode;
252 * when no dentry is available, set it to NULL instead.
253 */
254static int __inode_security_revalidate(struct inode *inode,
255 struct dentry *opt_dentry,
256 bool may_sleep)
257{
258 struct inode_security_struct *isec = inode->i_security;
259
260 might_sleep_if(may_sleep);
261
262 if (isec->initialized == LABEL_INVALID) {
263 if (!may_sleep)
264 return -ECHILD;
265
266 /*
267 * Try reloading the inode security label. This will fail if
268 * @opt_dentry is NULL and no dentry for this inode can be
269 * found; in that case, continue using the old label.
270 */
271 inode_doinit_with_dentry(inode, opt_dentry);
272 }
273 return 0;
274}
275
276static void inode_security_revalidate(struct inode *inode)
277{
278 __inode_security_revalidate(inode, NULL, true);
279}
280
281static struct inode_security_struct *inode_security_novalidate(struct inode *inode)
282{
283 return inode->i_security;
284}
285
286static struct inode_security_struct *inode_security_rcu(struct inode *inode, bool rcu)
287{
288 int error;
289
290 error = __inode_security_revalidate(inode, NULL, !rcu);
291 if (error)
292 return ERR_PTR(error);
293 return inode->i_security;
294}
295
245/* 296/*
246 * Get the security label of an inode. 297 * Get the security label of an inode.
247 */ 298 */
248static struct inode_security_struct *inode_security(struct inode *inode) 299static struct inode_security_struct *inode_security(struct inode *inode)
249{ 300{
301 __inode_security_revalidate(inode, NULL, true);
250 return inode->i_security; 302 return inode->i_security;
251} 303}
252 304
@@ -257,6 +309,7 @@ static struct inode_security_struct *backing_inode_security(struct dentry *dentr
257{ 309{
258 struct inode *inode = d_backing_inode(dentry); 310 struct inode *inode = d_backing_inode(dentry);
259 311
312 __inode_security_revalidate(inode, dentry, true);
260 return inode->i_security; 313 return inode->i_security;
261} 314}
262 315
@@ -363,8 +416,6 @@ static const char *labeling_behaviors[7] = {
363 "uses native labeling", 416 "uses native labeling",
364}; 417};
365 418
366static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
367
368static inline int inode_doinit(struct inode *inode) 419static inline int inode_doinit(struct inode *inode)
369{ 420{
370 return inode_doinit_with_dentry(inode, NULL); 421 return inode_doinit_with_dentry(inode, NULL);
@@ -1655,6 +1706,7 @@ static inline int dentry_has_perm(const struct cred *cred,
1655 1706
1656 ad.type = LSM_AUDIT_DATA_DENTRY; 1707 ad.type = LSM_AUDIT_DATA_DENTRY;
1657 ad.u.dentry = dentry; 1708 ad.u.dentry = dentry;
1709 __inode_security_revalidate(inode, dentry, true);
1658 return inode_has_perm(cred, inode, av, &ad); 1710 return inode_has_perm(cred, inode, av, &ad);
1659} 1711}
1660 1712
@@ -1670,6 +1722,7 @@ static inline int path_has_perm(const struct cred *cred,
1670 1722
1671 ad.type = LSM_AUDIT_DATA_PATH; 1723 ad.type = LSM_AUDIT_DATA_PATH;
1672 ad.u.path = *path; 1724 ad.u.path = *path;
1725 __inode_security_revalidate(inode, path->dentry, true);
1673 return inode_has_perm(cred, inode, av, &ad); 1726 return inode_has_perm(cred, inode, av, &ad);
1674} 1727}
1675 1728
@@ -2871,7 +2924,9 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode,
2871 ad.type = LSM_AUDIT_DATA_DENTRY; 2924 ad.type = LSM_AUDIT_DATA_DENTRY;
2872 ad.u.dentry = dentry; 2925 ad.u.dentry = dentry;
2873 sid = cred_sid(cred); 2926 sid = cred_sid(cred);
2874 isec = inode_security(inode); 2927 isec = inode_security_rcu(inode, rcu);
2928 if (IS_ERR(isec))
2929 return PTR_ERR(isec);
2875 2930
2876 return avc_has_perm_flags(sid, isec->sid, isec->sclass, FILE__READ, &ad, 2931 return avc_has_perm_flags(sid, isec->sid, isec->sclass, FILE__READ, &ad,
2877 rcu ? MAY_NOT_BLOCK : 0); 2932 rcu ? MAY_NOT_BLOCK : 0);
@@ -2923,7 +2978,9 @@ static int selinux_inode_permission(struct inode *inode, int mask)
2923 perms = file_mask_to_av(inode->i_mode, mask); 2978 perms = file_mask_to_av(inode->i_mode, mask);
2924 2979
2925 sid = cred_sid(cred); 2980 sid = cred_sid(cred);
2926 isec = inode_security(inode); 2981 isec = inode_security_rcu(inode, flags & MAY_NOT_BLOCK);
2982 if (IS_ERR(isec))
2983 return PTR_ERR(isec);
2927 2984
2928 rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass, perms, 0, &avd); 2985 rc = avc_has_perm_noaudit(sid, isec->sid, isec->sclass, perms, 0, &avd);
2929 audited = avc_audit_required(perms, &avd, rc, 2986 audited = avc_audit_required(perms, &avd, rc,
@@ -3232,6 +3289,7 @@ static int selinux_file_permission(struct file *file, int mask)
3232 /* No change since file_open check. */ 3289 /* No change since file_open check. */
3233 return 0; 3290 return 0;
3234 3291
3292 inode_security_revalidate(inode);
3235 return selinux_revalidate_file_permission(file, mask); 3293 return selinux_revalidate_file_permission(file, mask);
3236} 3294}
3237 3295
@@ -3537,6 +3595,7 @@ static int selinux_file_open(struct file *file, const struct cred *cred)
3537 * new inode label or new policy. 3595 * new inode label or new policy.
3538 * This check is not redundant - do not remove. 3596 * This check is not redundant - do not remove.
3539 */ 3597 */
3598 inode_security_revalidate(file_inode(file));
3540 return file_path_has_perm(cred, file, open_file_to_av(file)); 3599 return file_path_has_perm(cred, file, open_file_to_av(file));
3541} 3600}
3542 3601
@@ -4078,7 +4137,7 @@ static int selinux_socket_post_create(struct socket *sock, int family,
4078 int type, int protocol, int kern) 4137 int type, int protocol, int kern)
4079{ 4138{
4080 const struct task_security_struct *tsec = current_security(); 4139 const struct task_security_struct *tsec = current_security();
4081 struct inode_security_struct *isec = inode_security(SOCK_INODE(sock)); 4140 struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(sock));
4082 struct sk_security_struct *sksec; 4141 struct sk_security_struct *sksec;
4083 int err = 0; 4142 int err = 0;
4084 4143
@@ -4278,9 +4337,9 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
4278 if (err) 4337 if (err)
4279 return err; 4338 return err;
4280 4339
4281 newisec = inode_security(SOCK_INODE(newsock)); 4340 newisec = inode_security_novalidate(SOCK_INODE(newsock));
4282 4341
4283 isec = inode_security(SOCK_INODE(sock)); 4342 isec = inode_security_novalidate(SOCK_INODE(sock));
4284 newisec->sclass = isec->sclass; 4343 newisec->sclass = isec->sclass;
4285 newisec->sid = isec->sid; 4344 newisec->sid = isec->sid;
4286 newisec->initialized = LABEL_INITIALIZED; 4345 newisec->initialized = LABEL_INITIALIZED;
@@ -4618,7 +4677,8 @@ static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
4618 4677
4619static void selinux_sock_graft(struct sock *sk, struct socket *parent) 4678static void selinux_sock_graft(struct sock *sk, struct socket *parent)
4620{ 4679{
4621 struct inode_security_struct *isec = inode_security(SOCK_INODE(parent)); 4680 struct inode_security_struct *isec =
4681 inode_security_novalidate(SOCK_INODE(parent));
4622 struct sk_security_struct *sksec = sk->sk_security; 4682 struct sk_security_struct *sksec = sk->sk_security;
4623 4683
4624 if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 || 4684 if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 ||