aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
authorChris Zankel <chris@zankel.net>2014-10-21 00:26:01 -0400
committerChris Zankel <chris@zankel.net>2014-10-21 00:26:01 -0400
commita13926db3e5ea5bbac297f59e9f35061f52892d3 (patch)
treeb794f25550b7dbbe9cc8eda81633df9023b4821c /security/selinux/hooks.c
parentf2589bff1ce8b94cebc044e5dfeac4d4e8701cbc (diff)
parentf114040e3ea6e07372334ade75d1ee0775c355e1 (diff)
Merge tag 'v3.18-rc1' into for_next
Linux 3.18-rc1
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c141
1 files changed, 81 insertions, 60 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b0e940497e23..e66314138b38 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -481,6 +481,7 @@ next_inode:
481 list_entry(sbsec->isec_head.next, 481 list_entry(sbsec->isec_head.next,
482 struct inode_security_struct, list); 482 struct inode_security_struct, list);
483 struct inode *inode = isec->inode; 483 struct inode *inode = isec->inode;
484 list_del_init(&isec->list);
484 spin_unlock(&sbsec->isec_lock); 485 spin_unlock(&sbsec->isec_lock);
485 inode = igrab(inode); 486 inode = igrab(inode);
486 if (inode) { 487 if (inode) {
@@ -489,7 +490,6 @@ next_inode:
489 iput(inode); 490 iput(inode);
490 } 491 }
491 spin_lock(&sbsec->isec_lock); 492 spin_lock(&sbsec->isec_lock);
492 list_del_init(&isec->list);
493 goto next_inode; 493 goto next_inode;
494 } 494 }
495 spin_unlock(&sbsec->isec_lock); 495 spin_unlock(&sbsec->isec_lock);
@@ -2097,6 +2097,41 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
2097 2097
2098/* binprm security operations */ 2098/* binprm security operations */
2099 2099
2100static int check_nnp_nosuid(const struct linux_binprm *bprm,
2101 const struct task_security_struct *old_tsec,
2102 const struct task_security_struct *new_tsec)
2103{
2104 int nnp = (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS);
2105 int nosuid = (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID);
2106 int rc;
2107
2108 if (!nnp && !nosuid)
2109 return 0; /* neither NNP nor nosuid */
2110
2111 if (new_tsec->sid == old_tsec->sid)
2112 return 0; /* No change in credentials */
2113
2114 /*
2115 * The only transitions we permit under NNP or nosuid
2116 * are transitions to bounded SIDs, i.e. SIDs that are
2117 * guaranteed to only be allowed a subset of the permissions
2118 * of the current SID.
2119 */
2120 rc = security_bounded_transition(old_tsec->sid, new_tsec->sid);
2121 if (rc) {
2122 /*
2123 * On failure, preserve the errno values for NNP vs nosuid.
2124 * NNP: Operation not permitted for caller.
2125 * nosuid: Permission denied to file.
2126 */
2127 if (nnp)
2128 return -EPERM;
2129 else
2130 return -EACCES;
2131 }
2132 return 0;
2133}
2134
2100static int selinux_bprm_set_creds(struct linux_binprm *bprm) 2135static int selinux_bprm_set_creds(struct linux_binprm *bprm)
2101{ 2136{
2102 const struct task_security_struct *old_tsec; 2137 const struct task_security_struct *old_tsec;
@@ -2133,14 +2168,10 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
2133 /* Reset exec SID on execve. */ 2168 /* Reset exec SID on execve. */
2134 new_tsec->exec_sid = 0; 2169 new_tsec->exec_sid = 0;
2135 2170
2136 /* 2171 /* Fail on NNP or nosuid if not an allowed transition. */
2137 * Minimize confusion: if no_new_privs or nosuid and a 2172 rc = check_nnp_nosuid(bprm, old_tsec, new_tsec);
2138 * transition is explicitly requested, then fail the exec. 2173 if (rc)
2139 */ 2174 return rc;
2140 if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)
2141 return -EPERM;
2142 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
2143 return -EACCES;
2144 } else { 2175 } else {
2145 /* Check for a default transition on this program. */ 2176 /* Check for a default transition on this program. */
2146 rc = security_transition_sid(old_tsec->sid, isec->sid, 2177 rc = security_transition_sid(old_tsec->sid, isec->sid,
@@ -2148,15 +2179,19 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
2148 &new_tsec->sid); 2179 &new_tsec->sid);
2149 if (rc) 2180 if (rc)
2150 return rc; 2181 return rc;
2182
2183 /*
2184 * Fallback to old SID on NNP or nosuid if not an allowed
2185 * transition.
2186 */
2187 rc = check_nnp_nosuid(bprm, old_tsec, new_tsec);
2188 if (rc)
2189 new_tsec->sid = old_tsec->sid;
2151 } 2190 }
2152 2191
2153 ad.type = LSM_AUDIT_DATA_PATH; 2192 ad.type = LSM_AUDIT_DATA_PATH;
2154 ad.u.path = bprm->file->f_path; 2193 ad.u.path = bprm->file->f_path;
2155 2194
2156 if ((bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) ||
2157 (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS))
2158 new_tsec->sid = old_tsec->sid;
2159
2160 if (new_tsec->sid == old_tsec->sid) { 2195 if (new_tsec->sid == old_tsec->sid) {
2161 rc = avc_has_perm(old_tsec->sid, isec->sid, 2196 rc = avc_has_perm(old_tsec->sid, isec->sid,
2162 SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad); 2197 SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad);
@@ -3346,14 +3381,12 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd,
3346 return err; 3381 return err;
3347} 3382}
3348 3383
3349static int selinux_file_set_fowner(struct file *file) 3384static void selinux_file_set_fowner(struct file *file)
3350{ 3385{
3351 struct file_security_struct *fsec; 3386 struct file_security_struct *fsec;
3352 3387
3353 fsec = file->f_security; 3388 fsec = file->f_security;
3354 fsec->fown_sid = current_sid(); 3389 fsec->fown_sid = current_sid();
3355
3356 return 0;
3357} 3390}
3358 3391
3359static int selinux_file_send_sigiotask(struct task_struct *tsk, 3392static int selinux_file_send_sigiotask(struct task_struct *tsk,
@@ -4272,15 +4305,15 @@ static int selinux_socket_unix_may_send(struct socket *sock,
4272 &ad); 4305 &ad);
4273} 4306}
4274 4307
4275static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family, 4308static int selinux_inet_sys_rcv_skb(struct net *ns, int ifindex,
4276 u32 peer_sid, 4309 char *addrp, u16 family, u32 peer_sid,
4277 struct common_audit_data *ad) 4310 struct common_audit_data *ad)
4278{ 4311{
4279 int err; 4312 int err;
4280 u32 if_sid; 4313 u32 if_sid;
4281 u32 node_sid; 4314 u32 node_sid;
4282 4315
4283 err = sel_netif_sid(ifindex, &if_sid); 4316 err = sel_netif_sid(ns, ifindex, &if_sid);
4284 if (err) 4317 if (err)
4285 return err; 4318 return err;
4286 err = avc_has_perm(peer_sid, if_sid, 4319 err = avc_has_perm(peer_sid, if_sid,
@@ -4373,8 +4406,8 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
4373 err = selinux_skb_peerlbl_sid(skb, family, &peer_sid); 4406 err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
4374 if (err) 4407 if (err)
4375 return err; 4408 return err;
4376 err = selinux_inet_sys_rcv_skb(skb->skb_iif, addrp, family, 4409 err = selinux_inet_sys_rcv_skb(sock_net(sk), skb->skb_iif,
4377 peer_sid, &ad); 4410 addrp, family, peer_sid, &ad);
4378 if (err) { 4411 if (err) {
4379 selinux_netlbl_err(skb, err, 0); 4412 selinux_netlbl_err(skb, err, 0);
4380 return err; 4413 return err;
@@ -4692,10 +4725,9 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
4692 err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm); 4725 err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm);
4693 if (err) { 4726 if (err) {
4694 if (err == -EINVAL) { 4727 if (err == -EINVAL) {
4695 audit_log(current->audit_context, GFP_KERNEL, AUDIT_SELINUX_ERR, 4728 WARN_ONCE(1, "selinux_nlmsg_perm: unrecognized netlink message:"
4696 "SELinux: unrecognized netlink message" 4729 " protocol=%hu nlmsg_type=%hu sclass=%hu\n",
4697 " type=%hu for sclass=%hu\n", 4730 sk->sk_protocol, nlh->nlmsg_type, sksec->sclass);
4698 nlh->nlmsg_type, sksec->sclass);
4699 if (!selinux_enforcing || security_get_allow_unknown()) 4731 if (!selinux_enforcing || security_get_allow_unknown())
4700 err = 0; 4732 err = 0;
4701 } 4733 }
@@ -4713,7 +4745,8 @@ out:
4713 4745
4714#ifdef CONFIG_NETFILTER 4746#ifdef CONFIG_NETFILTER
4715 4747
4716static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, 4748static unsigned int selinux_ip_forward(struct sk_buff *skb,
4749 const struct net_device *indev,
4717 u16 family) 4750 u16 family)
4718{ 4751{
4719 int err; 4752 int err;
@@ -4739,14 +4772,14 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
4739 4772
4740 ad.type = LSM_AUDIT_DATA_NET; 4773 ad.type = LSM_AUDIT_DATA_NET;
4741 ad.u.net = &net; 4774 ad.u.net = &net;
4742 ad.u.net->netif = ifindex; 4775 ad.u.net->netif = indev->ifindex;
4743 ad.u.net->family = family; 4776 ad.u.net->family = family;
4744 if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0) 4777 if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
4745 return NF_DROP; 4778 return NF_DROP;
4746 4779
4747 if (peerlbl_active) { 4780 if (peerlbl_active) {
4748 err = selinux_inet_sys_rcv_skb(ifindex, addrp, family, 4781 err = selinux_inet_sys_rcv_skb(dev_net(indev), indev->ifindex,
4749 peer_sid, &ad); 4782 addrp, family, peer_sid, &ad);
4750 if (err) { 4783 if (err) {
4751 selinux_netlbl_err(skb, err, 1); 4784 selinux_netlbl_err(skb, err, 1);
4752 return NF_DROP; 4785 return NF_DROP;
@@ -4775,7 +4808,7 @@ static unsigned int selinux_ipv4_forward(const struct nf_hook_ops *ops,
4775 const struct net_device *out, 4808 const struct net_device *out,
4776 int (*okfn)(struct sk_buff *)) 4809 int (*okfn)(struct sk_buff *))
4777{ 4810{
4778 return selinux_ip_forward(skb, in->ifindex, PF_INET); 4811 return selinux_ip_forward(skb, in, PF_INET);
4779} 4812}
4780 4813
4781#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 4814#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -4785,7 +4818,7 @@ static unsigned int selinux_ipv6_forward(const struct nf_hook_ops *ops,
4785 const struct net_device *out, 4818 const struct net_device *out,
4786 int (*okfn)(struct sk_buff *)) 4819 int (*okfn)(struct sk_buff *))
4787{ 4820{
4788 return selinux_ip_forward(skb, in->ifindex, PF_INET6); 4821 return selinux_ip_forward(skb, in, PF_INET6);
4789} 4822}
4790#endif /* IPV6 */ 4823#endif /* IPV6 */
4791 4824
@@ -4873,11 +4906,13 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
4873 return NF_ACCEPT; 4906 return NF_ACCEPT;
4874} 4907}
4875 4908
4876static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, 4909static unsigned int selinux_ip_postroute(struct sk_buff *skb,
4910 const struct net_device *outdev,
4877 u16 family) 4911 u16 family)
4878{ 4912{
4879 u32 secmark_perm; 4913 u32 secmark_perm;
4880 u32 peer_sid; 4914 u32 peer_sid;
4915 int ifindex = outdev->ifindex;
4881 struct sock *sk; 4916 struct sock *sk;
4882 struct common_audit_data ad; 4917 struct common_audit_data ad;
4883 struct lsm_network_audit net = {0,}; 4918 struct lsm_network_audit net = {0,};
@@ -4958,6 +4993,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4958 case PF_INET6: 4993 case PF_INET6:
4959 if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) 4994 if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
4960 return NF_ACCEPT; 4995 return NF_ACCEPT;
4996 break;
4961 default: 4997 default:
4962 return NF_DROP_ERR(-ECONNREFUSED); 4998 return NF_DROP_ERR(-ECONNREFUSED);
4963 } 4999 }
@@ -4989,7 +5025,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4989 u32 if_sid; 5025 u32 if_sid;
4990 u32 node_sid; 5026 u32 node_sid;
4991 5027
4992 if (sel_netif_sid(ifindex, &if_sid)) 5028 if (sel_netif_sid(dev_net(outdev), ifindex, &if_sid))
4993 return NF_DROP; 5029 return NF_DROP;
4994 if (avc_has_perm(peer_sid, if_sid, 5030 if (avc_has_perm(peer_sid, if_sid,
4995 SECCLASS_NETIF, NETIF__EGRESS, &ad)) 5031 SECCLASS_NETIF, NETIF__EGRESS, &ad))
@@ -5011,7 +5047,7 @@ static unsigned int selinux_ipv4_postroute(const struct nf_hook_ops *ops,
5011 const struct net_device *out, 5047 const struct net_device *out,
5012 int (*okfn)(struct sk_buff *)) 5048 int (*okfn)(struct sk_buff *))
5013{ 5049{
5014 return selinux_ip_postroute(skb, out->ifindex, PF_INET); 5050 return selinux_ip_postroute(skb, out, PF_INET);
5015} 5051}
5016 5052
5017#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 5053#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -5021,7 +5057,7 @@ static unsigned int selinux_ipv6_postroute(const struct nf_hook_ops *ops,
5021 const struct net_device *out, 5057 const struct net_device *out,
5022 int (*okfn)(struct sk_buff *)) 5058 int (*okfn)(struct sk_buff *))
5023{ 5059{
5024 return selinux_ip_postroute(skb, out->ifindex, PF_INET6); 5060 return selinux_ip_postroute(skb, out, PF_INET6);
5025} 5061}
5026#endif /* IPV6 */ 5062#endif /* IPV6 */
5027 5063
@@ -6035,7 +6071,7 @@ security_initcall(selinux_init);
6035 6071
6036#if defined(CONFIG_NETFILTER) 6072#if defined(CONFIG_NETFILTER)
6037 6073
6038static struct nf_hook_ops selinux_ipv4_ops[] = { 6074static struct nf_hook_ops selinux_nf_ops[] = {
6039 { 6075 {
6040 .hook = selinux_ipv4_postroute, 6076 .hook = selinux_ipv4_postroute,
6041 .owner = THIS_MODULE, 6077 .owner = THIS_MODULE,
@@ -6056,12 +6092,8 @@ static struct nf_hook_ops selinux_ipv4_ops[] = {
6056 .pf = NFPROTO_IPV4, 6092 .pf = NFPROTO_IPV4,
6057 .hooknum = NF_INET_LOCAL_OUT, 6093 .hooknum = NF_INET_LOCAL_OUT,
6058 .priority = NF_IP_PRI_SELINUX_FIRST, 6094 .priority = NF_IP_PRI_SELINUX_FIRST,
6059 } 6095 },
6060};
6061
6062#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 6096#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
6063
6064static struct nf_hook_ops selinux_ipv6_ops[] = {
6065 { 6097 {
6066 .hook = selinux_ipv6_postroute, 6098 .hook = selinux_ipv6_postroute,
6067 .owner = THIS_MODULE, 6099 .owner = THIS_MODULE,
@@ -6075,32 +6107,24 @@ static struct nf_hook_ops selinux_ipv6_ops[] = {
6075 .pf = NFPROTO_IPV6, 6107 .pf = NFPROTO_IPV6,
6076 .hooknum = NF_INET_FORWARD, 6108 .hooknum = NF_INET_FORWARD,
6077 .priority = NF_IP6_PRI_SELINUX_FIRST, 6109 .priority = NF_IP6_PRI_SELINUX_FIRST,
6078 } 6110 },
6079};
6080
6081#endif /* IPV6 */ 6111#endif /* IPV6 */
6112};
6082 6113
6083static int __init selinux_nf_ip_init(void) 6114static int __init selinux_nf_ip_init(void)
6084{ 6115{
6085 int err = 0; 6116 int err;
6086 6117
6087 if (!selinux_enabled) 6118 if (!selinux_enabled)
6088 goto out; 6119 return 0;
6089 6120
6090 printk(KERN_DEBUG "SELinux: Registering netfilter hooks\n"); 6121 printk(KERN_DEBUG "SELinux: Registering netfilter hooks\n");
6091 6122
6092 err = nf_register_hooks(selinux_ipv4_ops, ARRAY_SIZE(selinux_ipv4_ops)); 6123 err = nf_register_hooks(selinux_nf_ops, ARRAY_SIZE(selinux_nf_ops));
6093 if (err)
6094 panic("SELinux: nf_register_hooks for IPv4: error %d\n", err);
6095
6096#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
6097 err = nf_register_hooks(selinux_ipv6_ops, ARRAY_SIZE(selinux_ipv6_ops));
6098 if (err) 6124 if (err)
6099 panic("SELinux: nf_register_hooks for IPv6: error %d\n", err); 6125 panic("SELinux: nf_register_hooks: error %d\n", err);
6100#endif /* IPV6 */
6101 6126
6102out: 6127 return 0;
6103 return err;
6104} 6128}
6105 6129
6106__initcall(selinux_nf_ip_init); 6130__initcall(selinux_nf_ip_init);
@@ -6110,10 +6134,7 @@ static void selinux_nf_ip_exit(void)
6110{ 6134{
6111 printk(KERN_DEBUG "SELinux: Unregistering netfilter hooks\n"); 6135 printk(KERN_DEBUG "SELinux: Unregistering netfilter hooks\n");
6112 6136
6113 nf_unregister_hooks(selinux_ipv4_ops, ARRAY_SIZE(selinux_ipv4_ops)); 6137 nf_unregister_hooks(selinux_nf_ops, ARRAY_SIZE(selinux_nf_ops));
6114#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
6115 nf_unregister_hooks(selinux_ipv6_ops, ARRAY_SIZE(selinux_ipv6_ops));
6116#endif /* IPV6 */
6117} 6138}
6118#endif 6139#endif
6119 6140