diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 153 |
1 files changed, 7 insertions, 146 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index ee2e781d11d7..ba808ef6babb 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -93,7 +93,6 @@ | |||
93 | 93 | ||
94 | extern unsigned int policydb_loaded_version; | 94 | extern unsigned int policydb_loaded_version; |
95 | extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm); | 95 | extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm); |
96 | extern int selinux_compat_net; | ||
97 | extern struct security_operations *security_ops; | 96 | extern struct security_operations *security_ops; |
98 | 97 | ||
99 | /* SECMARK reference count */ | 98 | /* SECMARK reference count */ |
@@ -4019,72 +4018,6 @@ static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family, | |||
4019 | SECCLASS_NODE, NODE__RECVFROM, ad); | 4018 | SECCLASS_NODE, NODE__RECVFROM, ad); |
4020 | } | 4019 | } |
4021 | 4020 | ||
4022 | static int selinux_sock_rcv_skb_iptables_compat(struct sock *sk, | ||
4023 | struct sk_buff *skb, | ||
4024 | struct avc_audit_data *ad, | ||
4025 | u16 family, | ||
4026 | char *addrp) | ||
4027 | { | ||
4028 | int err; | ||
4029 | struct sk_security_struct *sksec = sk->sk_security; | ||
4030 | u16 sk_class; | ||
4031 | u32 netif_perm, node_perm, recv_perm; | ||
4032 | u32 port_sid, node_sid, if_sid, sk_sid; | ||
4033 | |||
4034 | sk_sid = sksec->sid; | ||
4035 | sk_class = sksec->sclass; | ||
4036 | |||
4037 | switch (sk_class) { | ||
4038 | case SECCLASS_UDP_SOCKET: | ||
4039 | netif_perm = NETIF__UDP_RECV; | ||
4040 | node_perm = NODE__UDP_RECV; | ||
4041 | recv_perm = UDP_SOCKET__RECV_MSG; | ||
4042 | break; | ||
4043 | case SECCLASS_TCP_SOCKET: | ||
4044 | netif_perm = NETIF__TCP_RECV; | ||
4045 | node_perm = NODE__TCP_RECV; | ||
4046 | recv_perm = TCP_SOCKET__RECV_MSG; | ||
4047 | break; | ||
4048 | case SECCLASS_DCCP_SOCKET: | ||
4049 | netif_perm = NETIF__DCCP_RECV; | ||
4050 | node_perm = NODE__DCCP_RECV; | ||
4051 | recv_perm = DCCP_SOCKET__RECV_MSG; | ||
4052 | break; | ||
4053 | default: | ||
4054 | netif_perm = NETIF__RAWIP_RECV; | ||
4055 | node_perm = NODE__RAWIP_RECV; | ||
4056 | recv_perm = 0; | ||
4057 | break; | ||
4058 | } | ||
4059 | |||
4060 | err = sel_netif_sid(skb->iif, &if_sid); | ||
4061 | if (err) | ||
4062 | return err; | ||
4063 | err = avc_has_perm(sk_sid, if_sid, SECCLASS_NETIF, netif_perm, ad); | ||
4064 | if (err) | ||
4065 | return err; | ||
4066 | |||
4067 | err = sel_netnode_sid(addrp, family, &node_sid); | ||
4068 | if (err) | ||
4069 | return err; | ||
4070 | err = avc_has_perm(sk_sid, node_sid, SECCLASS_NODE, node_perm, ad); | ||
4071 | if (err) | ||
4072 | return err; | ||
4073 | |||
4074 | if (!recv_perm) | ||
4075 | return 0; | ||
4076 | err = sel_netport_sid(sk->sk_protocol, | ||
4077 | ntohs(ad->u.net.sport), &port_sid); | ||
4078 | if (unlikely(err)) { | ||
4079 | printk(KERN_WARNING | ||
4080 | "SELinux: failure in" | ||
4081 | " selinux_sock_rcv_skb_iptables_compat()," | ||
4082 | " network port label not found\n"); | ||
4083 | return err; | ||
4084 | } | ||
4085 | return avc_has_perm(sk_sid, port_sid, sk_class, recv_perm, ad); | ||
4086 | } | ||
4087 | |||
4088 | static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, | 4021 | static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, |
4089 | u16 family) | 4022 | u16 family) |
4090 | { | 4023 | { |
@@ -4102,14 +4035,12 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, | |||
4102 | if (err) | 4035 | if (err) |
4103 | return err; | 4036 | return err; |
4104 | 4037 | ||
4105 | if (selinux_compat_net) | 4038 | if (selinux_secmark_enabled()) { |
4106 | err = selinux_sock_rcv_skb_iptables_compat(sk, skb, &ad, | ||
4107 | family, addrp); | ||
4108 | else if (selinux_secmark_enabled()) | ||
4109 | err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET, | 4039 | err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET, |
4110 | PACKET__RECV, &ad); | 4040 | PACKET__RECV, &ad); |
4111 | if (err) | 4041 | if (err) |
4112 | return err; | 4042 | return err; |
4043 | } | ||
4113 | 4044 | ||
4114 | if (selinux_policycap_netpeer) { | 4045 | if (selinux_policycap_netpeer) { |
4115 | err = selinux_skb_peerlbl_sid(skb, family, &peer_sid); | 4046 | err = selinux_skb_peerlbl_sid(skb, family, &peer_sid); |
@@ -4151,7 +4082,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
4151 | * to the selinux_sock_rcv_skb_compat() function to deal with the | 4082 | * to the selinux_sock_rcv_skb_compat() function to deal with the |
4152 | * special handling. We do this in an attempt to keep this function | 4083 | * special handling. We do this in an attempt to keep this function |
4153 | * as fast and as clean as possible. */ | 4084 | * as fast and as clean as possible. */ |
4154 | if (selinux_compat_net || !selinux_policycap_netpeer) | 4085 | if (!selinux_policycap_netpeer) |
4155 | return selinux_sock_rcv_skb_compat(sk, skb, family); | 4086 | return selinux_sock_rcv_skb_compat(sk, skb, family); |
4156 | 4087 | ||
4157 | secmark_active = selinux_secmark_enabled(); | 4088 | secmark_active = selinux_secmark_enabled(); |
@@ -4516,71 +4447,6 @@ static unsigned int selinux_ipv4_output(unsigned int hooknum, | |||
4516 | return selinux_ip_output(skb, PF_INET); | 4447 | return selinux_ip_output(skb, PF_INET); |
4517 | } | 4448 | } |
4518 | 4449 | ||
4519 | static int selinux_ip_postroute_iptables_compat(struct sock *sk, | ||
4520 | int ifindex, | ||
4521 | struct avc_audit_data *ad, | ||
4522 | u16 family, char *addrp) | ||
4523 | { | ||
4524 | int err; | ||
4525 | struct sk_security_struct *sksec = sk->sk_security; | ||
4526 | u16 sk_class; | ||
4527 | u32 netif_perm, node_perm, send_perm; | ||
4528 | u32 port_sid, node_sid, if_sid, sk_sid; | ||
4529 | |||
4530 | sk_sid = sksec->sid; | ||
4531 | sk_class = sksec->sclass; | ||
4532 | |||
4533 | switch (sk_class) { | ||
4534 | case SECCLASS_UDP_SOCKET: | ||
4535 | netif_perm = NETIF__UDP_SEND; | ||
4536 | node_perm = NODE__UDP_SEND; | ||
4537 | send_perm = UDP_SOCKET__SEND_MSG; | ||
4538 | break; | ||
4539 | case SECCLASS_TCP_SOCKET: | ||
4540 | netif_perm = NETIF__TCP_SEND; | ||
4541 | node_perm = NODE__TCP_SEND; | ||
4542 | send_perm = TCP_SOCKET__SEND_MSG; | ||
4543 | break; | ||
4544 | case SECCLASS_DCCP_SOCKET: | ||
4545 | netif_perm = NETIF__DCCP_SEND; | ||
4546 | node_perm = NODE__DCCP_SEND; | ||
4547 | send_perm = DCCP_SOCKET__SEND_MSG; | ||
4548 | break; | ||
4549 | default: | ||
4550 | netif_perm = NETIF__RAWIP_SEND; | ||
4551 | node_perm = NODE__RAWIP_SEND; | ||
4552 | send_perm = 0; | ||
4553 | break; | ||
4554 | } | ||
4555 | |||
4556 | err = sel_netif_sid(ifindex, &if_sid); | ||
4557 | if (err) | ||
4558 | return err; | ||
4559 | err = avc_has_perm(sk_sid, if_sid, SECCLASS_NETIF, netif_perm, ad); | ||
4560 | return err; | ||
4561 | |||
4562 | err = sel_netnode_sid(addrp, family, &node_sid); | ||
4563 | if (err) | ||
4564 | return err; | ||
4565 | err = avc_has_perm(sk_sid, node_sid, SECCLASS_NODE, node_perm, ad); | ||
4566 | if (err) | ||
4567 | return err; | ||
4568 | |||
4569 | if (send_perm != 0) | ||
4570 | return 0; | ||
4571 | |||
4572 | err = sel_netport_sid(sk->sk_protocol, | ||
4573 | ntohs(ad->u.net.dport), &port_sid); | ||
4574 | if (unlikely(err)) { | ||
4575 | printk(KERN_WARNING | ||
4576 | "SELinux: failure in" | ||
4577 | " selinux_ip_postroute_iptables_compat()," | ||
4578 | " network port label not found\n"); | ||
4579 | return err; | ||
4580 | } | ||
4581 | return avc_has_perm(sk_sid, port_sid, sk_class, send_perm, ad); | ||
4582 | } | ||
4583 | |||
4584 | static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, | 4450 | static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, |
4585 | int ifindex, | 4451 | int ifindex, |
4586 | u16 family) | 4452 | u16 family) |
@@ -4601,15 +4467,10 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, | |||
4601 | if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto)) | 4467 | if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto)) |
4602 | return NF_DROP; | 4468 | return NF_DROP; |
4603 | 4469 | ||
4604 | if (selinux_compat_net) { | 4470 | if (selinux_secmark_enabled()) |
4605 | if (selinux_ip_postroute_iptables_compat(skb->sk, ifindex, | ||
4606 | &ad, family, addrp)) | ||
4607 | return NF_DROP; | ||
4608 | } else if (selinux_secmark_enabled()) { | ||
4609 | if (avc_has_perm(sksec->sid, skb->secmark, | 4471 | if (avc_has_perm(sksec->sid, skb->secmark, |
4610 | SECCLASS_PACKET, PACKET__SEND, &ad)) | 4472 | SECCLASS_PACKET, PACKET__SEND, &ad)) |
4611 | return NF_DROP; | 4473 | return NF_DROP; |
4612 | } | ||
4613 | 4474 | ||
4614 | if (selinux_policycap_netpeer) | 4475 | if (selinux_policycap_netpeer) |
4615 | if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto)) | 4476 | if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto)) |
@@ -4633,7 +4494,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, | |||
4633 | * to the selinux_ip_postroute_compat() function to deal with the | 4494 | * to the selinux_ip_postroute_compat() function to deal with the |
4634 | * special handling. We do this in an attempt to keep this function | 4495 | * special handling. We do this in an attempt to keep this function |
4635 | * as fast and as clean as possible. */ | 4496 | * as fast and as clean as possible. */ |
4636 | if (selinux_compat_net || !selinux_policycap_netpeer) | 4497 | if (!selinux_policycap_netpeer) |
4637 | return selinux_ip_postroute_compat(skb, ifindex, family); | 4498 | return selinux_ip_postroute_compat(skb, ifindex, family); |
4638 | #ifdef CONFIG_XFRM | 4499 | #ifdef CONFIG_XFRM |
4639 | /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec | 4500 | /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec |