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.c70
1 files changed, 44 insertions, 26 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b02315183b2f..99c4675952f7 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1567,8 +1567,15 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1567 /* Called from d_instantiate or d_splice_alias. */ 1567 /* Called from d_instantiate or d_splice_alias. */
1568 dentry = dget(opt_dentry); 1568 dentry = dget(opt_dentry);
1569 } else { 1569 } else {
1570 /* 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 */
1571 dentry = d_find_alias(inode); 1576 dentry = d_find_alias(inode);
1577 if (!dentry)
1578 dentry = d_find_any_alias(inode);
1572 } 1579 }
1573 if (!dentry) { 1580 if (!dentry) {
1574 /* 1581 /*
@@ -1673,14 +1680,19 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1673 if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) { 1680 if ((sbsec->flags & SE_SBGENFS) && !S_ISLNK(inode->i_mode)) {
1674 /* We must have a dentry to determine the label on 1681 /* We must have a dentry to determine the label on
1675 * procfs inodes */ 1682 * procfs inodes */
1676 if (opt_dentry) 1683 if (opt_dentry) {
1677 /* Called from d_instantiate or 1684 /* Called from d_instantiate or
1678 * d_splice_alias. */ 1685 * d_splice_alias. */
1679 dentry = dget(opt_dentry); 1686 dentry = dget(opt_dentry);
1680 else 1687 } else {
1681 /* Called from selinux_complete_init, try to 1688 /* Called from selinux_complete_init, try to
1682 * find a dentry. */ 1689 * find a dentry. Some filesystems really want
1690 * a connected one, so try that first.
1691 */
1683 dentry = d_find_alias(inode); 1692 dentry = d_find_alias(inode);
1693 if (!dentry)
1694 dentry = d_find_any_alias(inode);
1695 }
1684 /* 1696 /*
1685 * This can be hit on boot when a file is accessed 1697 * This can be hit on boot when a file is accessed
1686 * before the policy is loaded. When we load policy we 1698 * before the policy is loaded. When we load policy we
@@ -4575,6 +4587,7 @@ static int selinux_socket_post_create(struct socket *sock, int family,
4575static 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)
4576{ 4588{
4577 struct sock *sk = sock->sk; 4589 struct sock *sk = sock->sk;
4590 struct sk_security_struct *sksec = sk->sk_security;
4578 u16 family; 4591 u16 family;
4579 int err; 4592 int err;
4580 4593
@@ -4586,11 +4599,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
4586 family = sk->sk_family; 4599 family = sk->sk_family;
4587 if (family == PF_INET || family == PF_INET6) { 4600 if (family == PF_INET || family == PF_INET6) {
4588 char *addrp; 4601 char *addrp;
4589 struct sk_security_struct *sksec = sk->sk_security;
4590 struct common_audit_data ad; 4602 struct common_audit_data ad;
4591 struct lsm_network_audit net = {0,}; 4603 struct lsm_network_audit net = {0,};
4592 struct sockaddr_in *addr4 = NULL; 4604 struct sockaddr_in *addr4 = NULL;
4593 struct sockaddr_in6 *addr6 = NULL; 4605 struct sockaddr_in6 *addr6 = NULL;
4606 u16 family_sa = address->sa_family;
4594 unsigned short snum; 4607 unsigned short snum;
4595 u32 sid, node_perm; 4608 u32 sid, node_perm;
4596 4609
@@ -4600,11 +4613,20 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
4600 * 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
4601 * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. 4614 * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET.
4602 */ 4615 */
4603 switch (address->sa_family) { 4616 switch (family_sa) {
4617 case AF_UNSPEC:
4604 case AF_INET: 4618 case AF_INET:
4605 if (addrlen < sizeof(struct sockaddr_in)) 4619 if (addrlen < sizeof(struct sockaddr_in))
4606 return -EINVAL; 4620 return -EINVAL;
4607 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 }
4608 snum = ntohs(addr4->sin_port); 4630 snum = ntohs(addr4->sin_port);
4609 addrp = (char *)&addr4->sin_addr.s_addr; 4631 addrp = (char *)&addr4->sin_addr.s_addr;
4610 break; 4632 break;
@@ -4616,15 +4638,14 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
4616 addrp = (char *)&addr6->sin6_addr.s6_addr; 4638 addrp = (char *)&addr6->sin6_addr.s6_addr;
4617 break; 4639 break;
4618 default: 4640 default:
4619 /* Note that SCTP services expect -EINVAL, whereas 4641 goto err_af;
4620 * others expect -EAFNOSUPPORT.
4621 */
4622 if (sksec->sclass == SECCLASS_SCTP_SOCKET)
4623 return -EINVAL;
4624 else
4625 return -EAFNOSUPPORT;
4626 } 4642 }
4627 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
4628 if (snum) { 4649 if (snum) {
4629 int low, high; 4650 int low, high;
4630 4651
@@ -4636,10 +4657,6 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
4636 snum, &sid); 4657 snum, &sid);
4637 if (err) 4658 if (err)
4638 goto out; 4659 goto out;
4639 ad.type = LSM_AUDIT_DATA_NET;
4640 ad.u.net = &net;
4641 ad.u.net->sport = htons(snum);
4642 ad.u.net->family = family;
4643 err = avc_has_perm(&selinux_state, 4660 err = avc_has_perm(&selinux_state,
4644 sksec->sid, sid, 4661 sksec->sid, sid,
4645 sksec->sclass, 4662 sksec->sclass,
@@ -4671,16 +4688,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
4671 break; 4688 break;
4672 } 4689 }
4673 4690
4674 err = sel_netnode_sid(addrp, family, &sid); 4691 err = sel_netnode_sid(addrp, family_sa, &sid);
4675 if (err) 4692 if (err)
4676 goto out; 4693 goto out;
4677 4694
4678 ad.type = LSM_AUDIT_DATA_NET; 4695 if (family_sa == AF_INET)
4679 ad.u.net = &net;
4680 ad.u.net->sport = htons(snum);
4681 ad.u.net->family = family;
4682
4683 if (address->sa_family == AF_INET)
4684 ad.u.net->v4info.saddr = addr4->sin_addr.s_addr; 4696 ad.u.net->v4info.saddr = addr4->sin_addr.s_addr;
4685 else 4697 else
4686 ad.u.net->v6info.saddr = addr6->sin6_addr; 4698 ad.u.net->v6info.saddr = addr6->sin6_addr;
@@ -4693,6 +4705,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
4693 } 4705 }
4694out: 4706out:
4695 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;
4696} 4713}
4697 4714
4698/* 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)
@@ -4770,7 +4787,7 @@ static int selinux_socket_connect_helper(struct socket *sock,
4770 ad.type = LSM_AUDIT_DATA_NET; 4787 ad.type = LSM_AUDIT_DATA_NET;
4771 ad.u.net = &net; 4788 ad.u.net = &net;
4772 ad.u.net->dport = htons(snum); 4789 ad.u.net->dport = htons(snum);
4773 ad.u.net->family = sk->sk_family; 4790 ad.u.net->family = address->sa_family;
4774 err = avc_has_perm(&selinux_state, 4791 err = avc_has_perm(&selinux_state,
4775 sksec->sid, sid, sksec->sclass, perm, &ad); 4792 sksec->sid, sid, sksec->sclass, perm, &ad);
4776 if (err) 4793 if (err)
@@ -5271,6 +5288,7 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname,
5271 while (walk_size < addrlen) { 5288 while (walk_size < addrlen) {
5272 addr = addr_buf; 5289 addr = addr_buf;
5273 switch (addr->sa_family) { 5290 switch (addr->sa_family) {
5291 case AF_UNSPEC:
5274 case AF_INET: 5292 case AF_INET:
5275 len = sizeof(struct sockaddr_in); 5293 len = sizeof(struct sockaddr_in);
5276 break; 5294 break;
@@ -5278,7 +5296,7 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname,
5278 len = sizeof(struct sockaddr_in6); 5296 len = sizeof(struct sockaddr_in6);
5279 break; 5297 break;
5280 default: 5298 default:
5281 return -EAFNOSUPPORT; 5299 return -EINVAL;
5282 } 5300 }
5283 5301
5284 err = -EINVAL; 5302 err = -EINVAL;