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.c77
1 files changed, 47 insertions, 30 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 4cafe6a19167..99c4675952f7 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -274,11 +274,10 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
274 * Try reloading inode security labels that have been marked as invalid. The 274 * Try reloading inode security labels that have been marked as invalid. The
275 * @may_sleep parameter indicates when sleeping and thus reloading labels is 275 * @may_sleep parameter indicates when sleeping and thus reloading labels is
276 * allowed; when set to false, returns -ECHILD when the label is 276 * allowed; when set to false, returns -ECHILD when the label is
277 * invalid. The @opt_dentry parameter should be set to a dentry of the inode; 277 * invalid. The @dentry parameter should be set to a dentry of the inode.
278 * when no dentry is available, set it to NULL instead.
279 */ 278 */
280static int __inode_security_revalidate(struct inode *inode, 279static int __inode_security_revalidate(struct inode *inode,
281 struct dentry *opt_dentry, 280 struct dentry *dentry,
282 bool may_sleep) 281 bool may_sleep)
283{ 282{
284 struct inode_security_struct *isec = inode->i_security; 283 struct inode_security_struct *isec = inode->i_security;
@@ -295,7 +294,7 @@ static int __inode_security_revalidate(struct inode *inode,
295 * @opt_dentry is NULL and no dentry for this inode can be 294 * @opt_dentry is NULL and no dentry for this inode can be
296 * found; in that case, continue using the old label. 295 * found; in that case, continue using the old label.
297 */ 296 */
298 inode_doinit_with_dentry(inode, opt_dentry); 297 inode_doinit_with_dentry(inode, dentry);
299 } 298 }
300 return 0; 299 return 0;
301} 300}
@@ -1568,8 +1567,15 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1568 /* Called from d_instantiate or d_splice_alias. */ 1567 /* Called from d_instantiate or d_splice_alias. */
1569 dentry = dget(opt_dentry); 1568 dentry = dget(opt_dentry);
1570 } else { 1569 } else {
1571 /* Called from selinux_complete_init, try to find a dentry. */ 1570 /*
1571 * Called from selinux_complete_init, try to find a dentry.
1572 * Some filesystems really want a connected one, so try
1573 * that first. We could split SECURITY_FS_USE_XATTR in
1574 * two, depending upon that...
1575 */
1572 dentry = d_find_alias(inode); 1576 dentry = d_find_alias(inode);
1577 if (!dentry)
1578 dentry = d_find_any_alias(inode);
1573 } 1579 }
1574 if (!dentry) { 1580 if (!dentry) {
1575 /* 1581 /*
@@ -1674,14 +1680,19 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1674 if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) { 1680 if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) {
1675 /* We must have a dentry to determine the label on 1681 /* We must have a dentry to determine the label on
1676 * procfs inodes */ 1682 * procfs inodes */
1677 if (opt_dentry) 1683 if (opt_dentry) {
1678 /* Called from d_instantiate or 1684 /* Called from d_instantiate or
1679 * d_splice_alias. */ 1685 * d_splice_alias. */
1680 dentry = dget(opt_dentry); 1686 dentry = dget(opt_dentry);
1681 else 1687 } else {
1682 /* Called from selinux_complete_init, try to 1688 /* Called from selinux_complete_init, try to
1683 * find a dentry. */ 1689 * find a dentry. Some filesystems really want
1690 * a connected one, so try that first.
1691 */
1684 dentry = d_find_alias(inode); 1692 dentry = d_find_alias(inode);
1693 if (!dentry)
1694 dentry = d_find_any_alias(inode);
1695 }
1685 /* 1696 /*
1686 * This can be hit on boot when a file is accessed 1697 * This can be hit on boot when a file is accessed
1687 * before the policy is loaded. When we load policy we 1698 * before the policy is loaded. When we load policy we
@@ -4576,6 +4587,7 @@ static int selinux_socket_post_create(struct socket *sock, int family,
4576static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) 4587static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
4577{ 4588{
4578 struct sock *sk = sock->sk; 4589 struct sock *sk = sock->sk;
4590 struct sk_security_struct *sksec = sk->sk_security;
4579 u16 family; 4591 u16 family;
4580 int err; 4592 int err;
4581 4593
@@ -4587,11 +4599,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
4587 family = sk->sk_family; 4599 family = sk->sk_family;
4588 if (family == PF_INET || family == PF_INET6) { 4600 if (family == PF_INET || family == PF_INET6) {
4589 char *addrp; 4601 char *addrp;
4590 struct sk_security_struct *sksec = sk->sk_security;
4591 struct common_audit_data ad; 4602 struct common_audit_data ad;
4592 struct lsm_network_audit net = {0,}; 4603 struct lsm_network_audit net = {0,};
4593 struct sockaddr_in *addr4 = NULL; 4604 struct sockaddr_in *addr4 = NULL;
4594 struct sockaddr_in6 *addr6 = NULL; 4605 struct sockaddr_in6 *addr6 = NULL;
4606 u16 family_sa = address->sa_family;
4595 unsigned short snum; 4607 unsigned short snum;
4596 u32 sid, node_perm; 4608 u32 sid, node_perm;
4597 4609
@@ -4601,11 +4613,20 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
4601 * need to check address->sa_family as it is possible to have 4613 * need to check address->sa_family as it is possible to have
4602 * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. 4614 * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET.
4603 */ 4615 */
4604 switch (address->sa_family) { 4616 switch (family_sa) {
4617 case AF_UNSPEC:
4605 case AF_INET: 4618 case AF_INET:
4606 if (addrlen < sizeof(struct sockaddr_in)) 4619 if (addrlen < sizeof(struct sockaddr_in))
4607 return -EINVAL; 4620 return -EINVAL;
4608 addr4 = (struct sockaddr_in *)address; 4621 addr4 = (struct sockaddr_in *)address;
4622 if (family_sa == AF_UNSPEC) {
4623 /* see __inet_bind(), we only want to allow
4624 * AF_UNSPEC if the address is INADDR_ANY
4625 */
4626 if (addr4->sin_addr.s_addr != htonl(INADDR_ANY))
4627 goto err_af;
4628 family_sa = AF_INET;
4629 }
4609 snum = ntohs(addr4->sin_port); 4630 snum = ntohs(addr4->sin_port);
4610 addrp = (char *)&addr4->sin_addr.s_addr; 4631 addrp = (char *)&addr4->sin_addr.s_addr;
4611 break; 4632 break;
@@ -4617,15 +4638,14 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
4617 addrp = (char *)&addr6->sin6_addr.s6_addr; 4638 addrp = (char *)&addr6->sin6_addr.s6_addr;
4618 break; 4639 break;
4619 default: 4640 default:
4620 /* Note that SCTP services expect -EINVAL, whereas 4641 goto err_af;
4621 * others expect -EAFNOSUPPORT.
4622 */
4623 if (sksec->sclass == SECCLASS_SCTP_SOCKET)
4624 return -EINVAL;
4625 else
4626 return -EAFNOSUPPORT;
4627 } 4642 }
4628 4643
4644 ad.type = LSM_AUDIT_DATA_NET;
4645 ad.u.net = &net;
4646 ad.u.net->sport = htons(snum);
4647 ad.u.net->family = family_sa;
4648
4629 if (snum) { 4649 if (snum) {
4630 int low, high; 4650 int low, high;
4631 4651
@@ -4637,10 +4657,6 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
4637 snum, &sid); 4657 snum, &sid);
4638 if (err) 4658 if (err)
4639 goto out; 4659 goto out;
4640 ad.type = LSM_AUDIT_DATA_NET;
4641 ad.u.net = &net;
4642 ad.u.net->sport = htons(snum);
4643 ad.u.net->family = family;
4644 err = avc_has_perm(&selinux_state, 4660 err = avc_has_perm(&selinux_state,
4645 sksec->sid, sid, 4661 sksec->sid, sid,
4646 sksec->sclass, 4662 sksec->sclass,
@@ -4672,16 +4688,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
4672 break; 4688 break;
4673 } 4689 }
4674 4690
4675 err = sel_netnode_sid(addrp, family, &sid); 4691 err = sel_netnode_sid(addrp, family_sa, &sid);
4676 if (err) 4692 if (err)
4677 goto out; 4693 goto out;
4678 4694
4679 ad.type = LSM_AUDIT_DATA_NET; 4695 if (family_sa == AF_INET)
4680 ad.u.net = &net;
4681 ad.u.net->sport = htons(snum);
4682 ad.u.net->family = family;
4683
4684 if (address->sa_family == AF_INET)
4685 ad.u.net->v4info.saddr = addr4->sin_addr.s_addr; 4696 ad.u.net->v4info.saddr = addr4->sin_addr.s_addr;
4686 else 4697 else
4687 ad.u.net->v6info.saddr = addr6->sin6_addr; 4698 ad.u.net->v6info.saddr = addr6->sin6_addr;
@@ -4694,6 +4705,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
4694 } 4705 }
4695out: 4706out:
4696 return err; 4707 return err;
4708err_af:
4709 /* Note that SCTP services expect -EINVAL, others -EAFNOSUPPORT. */
4710 if (sksec->sclass == SECCLASS_SCTP_SOCKET)
4711 return -EINVAL;
4712 return -EAFNOSUPPORT;
4697} 4713}
4698 4714
4699/* This supports connect(2) and SCTP connect services such as sctp_connectx(3) 4715/* This supports connect(2) and SCTP connect services such as sctp_connectx(3)
@@ -4771,7 +4787,7 @@ static int selinux_socket_connect_helper(struct socket *sock,
4771 ad.type = LSM_AUDIT_DATA_NET; 4787 ad.type = LSM_AUDIT_DATA_NET;
4772 ad.u.net = &net; 4788 ad.u.net = &net;
4773 ad.u.net->dport = htons(snum); 4789 ad.u.net->dport = htons(snum);
4774 ad.u.net->family = sk->sk_family; 4790 ad.u.net->family = address->sa_family;
4775 err = avc_has_perm(&selinux_state, 4791 err = avc_has_perm(&selinux_state,
4776 sksec->sid, sid, sksec->sclass, perm, &ad); 4792 sksec->sid, sid, sksec->sclass, perm, &ad);
4777 if (err) 4793 if (err)
@@ -5272,6 +5288,7 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname,
5272 while (walk_size < addrlen) { 5288 while (walk_size < addrlen) {
5273 addr = addr_buf; 5289 addr = addr_buf;
5274 switch (addr->sa_family) { 5290 switch (addr->sa_family) {
5291 case AF_UNSPEC:
5275 case AF_INET: 5292 case AF_INET:
5276 len = sizeof(struct sockaddr_in); 5293 len = sizeof(struct sockaddr_in);
5277 break; 5294 break;
@@ -5279,7 +5296,7 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname,
5279 len = sizeof(struct sockaddr_in6); 5296 len = sizeof(struct sockaddr_in6);
5280 break; 5297 break;
5281 default: 5298 default:
5282 return -EAFNOSUPPORT; 5299 return -EINVAL;
5283 } 5300 }
5284 5301
5285 err = -EINVAL; 5302 err = -EINVAL;