aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2014-09-10 17:09:57 -0400
committerPaul Moore <pmoore@redhat.com>2014-09-10 17:09:57 -0400
commitcbe0d6e8794f1da6cac1ea3864d2cfaf0bf87c8e (patch)
tree36d99ec1ecc4fec26ede0516059e611729a5afb9 /security/selinux/hooks.c
parent25db6bea1ff5a78ef493eefdcbb9c1d27134e560 (diff)
selinux: make the netif cache namespace aware
While SELinux largely ignores namespaces, for good reason, there are some places where it needs to at least be aware of namespaces in order to function correctly. Network namespaces are one example. Basic awareness of network namespaces are necessary in order to match a network interface's index number to an actual network device. This patch corrects a problem with network interfaces added to a non-init namespace, and can be reproduced with the following commands: [NOTE: the NetLabel configuration is here only to active the dynamic networking controls ] # netlabelctl unlbl add default address:0.0.0.0/0 \ label:system_u:object_r:unlabeled_t:s0 # netlabelctl unlbl add default address:::/0 \ label:system_u:object_r:unlabeled_t:s0 # netlabelctl cipsov4 add pass doi:100 tags:1 # netlabelctl map add domain:lspp_test_netlabel_t \ protocol:cipsov4,100 # ip link add type veth # ip netns add myns # ip link set veth1 netns myns # ip a add dev veth0 10.250.13.100/24 # ip netns exec myns ip a add dev veth1 10.250.13.101/24 # ip l set veth0 up # ip netns exec myns ip l set veth1 up # ping -c 1 10.250.13.101 # ip netns exec myns ping -c 1 10.250.13.100 Reported-by: Jiri Jaburek <jjaburek@redhat.com> Signed-off-by: Paul Moore <pmoore@redhat.com>
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 50978d3183ea..5eb512b7ac31 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4307,15 +4307,15 @@ static int selinux_socket_unix_may_send(struct socket *sock,
4307 &ad); 4307 &ad);
4308} 4308}
4309 4309
4310static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family, 4310static int selinux_inet_sys_rcv_skb(struct net *ns, int ifindex,
4311 u32 peer_sid, 4311 char *addrp, u16 family, u32 peer_sid,
4312 struct common_audit_data *ad) 4312 struct common_audit_data *ad)
4313{ 4313{
4314 int err; 4314 int err;
4315 u32 if_sid; 4315 u32 if_sid;
4316 u32 node_sid; 4316 u32 node_sid;
4317 4317
4318 err = sel_netif_sid(ifindex, &if_sid); 4318 err = sel_netif_sid(ns, ifindex, &if_sid);
4319 if (err) 4319 if (err)
4320 return err; 4320 return err;
4321 err = avc_has_perm(peer_sid, if_sid, 4321 err = avc_has_perm(peer_sid, if_sid,
@@ -4408,8 +4408,8 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
4408 err = selinux_skb_peerlbl_sid(skb, family, &peer_sid); 4408 err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
4409 if (err) 4409 if (err)
4410 return err; 4410 return err;
4411 err = selinux_inet_sys_rcv_skb(skb->skb_iif, addrp, family, 4411 err = selinux_inet_sys_rcv_skb(sock_net(sk), skb->skb_iif,
4412 peer_sid, &ad); 4412 addrp, family, peer_sid, &ad);
4413 if (err) { 4413 if (err) {
4414 selinux_netlbl_err(skb, err, 0); 4414 selinux_netlbl_err(skb, err, 0);
4415 return err; 4415 return err;
@@ -4748,7 +4748,8 @@ out:
4748 4748
4749#ifdef CONFIG_NETFILTER 4749#ifdef CONFIG_NETFILTER
4750 4750
4751static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, 4751static unsigned int selinux_ip_forward(struct sk_buff *skb,
4752 const struct net_device *indev,
4752 u16 family) 4753 u16 family)
4753{ 4754{
4754 int err; 4755 int err;
@@ -4774,14 +4775,14 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
4774 4775
4775 ad.type = LSM_AUDIT_DATA_NET; 4776 ad.type = LSM_AUDIT_DATA_NET;
4776 ad.u.net = &net; 4777 ad.u.net = &net;
4777 ad.u.net->netif = ifindex; 4778 ad.u.net->netif = indev->ifindex;
4778 ad.u.net->family = family; 4779 ad.u.net->family = family;
4779 if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0) 4780 if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
4780 return NF_DROP; 4781 return NF_DROP;
4781 4782
4782 if (peerlbl_active) { 4783 if (peerlbl_active) {
4783 err = selinux_inet_sys_rcv_skb(ifindex, addrp, family, 4784 err = selinux_inet_sys_rcv_skb(dev_net(indev), indev->ifindex,
4784 peer_sid, &ad); 4785 addrp, family, peer_sid, &ad);
4785 if (err) { 4786 if (err) {
4786 selinux_netlbl_err(skb, err, 1); 4787 selinux_netlbl_err(skb, err, 1);
4787 return NF_DROP; 4788 return NF_DROP;
@@ -4810,7 +4811,7 @@ static unsigned int selinux_ipv4_forward(const struct nf_hook_ops *ops,
4810 const struct net_device *out, 4811 const struct net_device *out,
4811 int (*okfn)(struct sk_buff *)) 4812 int (*okfn)(struct sk_buff *))
4812{ 4813{
4813 return selinux_ip_forward(skb, in->ifindex, PF_INET); 4814 return selinux_ip_forward(skb, in, PF_INET);
4814} 4815}
4815 4816
4816#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 4817#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -4820,7 +4821,7 @@ static unsigned int selinux_ipv6_forward(const struct nf_hook_ops *ops,
4820 const struct net_device *out, 4821 const struct net_device *out,
4821 int (*okfn)(struct sk_buff *)) 4822 int (*okfn)(struct sk_buff *))
4822{ 4823{
4823 return selinux_ip_forward(skb, in->ifindex, PF_INET6); 4824 return selinux_ip_forward(skb, in, PF_INET6);
4824} 4825}
4825#endif /* IPV6 */ 4826#endif /* IPV6 */
4826 4827
@@ -4908,11 +4909,13 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
4908 return NF_ACCEPT; 4909 return NF_ACCEPT;
4909} 4910}
4910 4911
4911static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, 4912static unsigned int selinux_ip_postroute(struct sk_buff *skb,
4913 const struct net_device *outdev,
4912 u16 family) 4914 u16 family)
4913{ 4915{
4914 u32 secmark_perm; 4916 u32 secmark_perm;
4915 u32 peer_sid; 4917 u32 peer_sid;
4918 int ifindex = outdev->ifindex;
4916 struct sock *sk; 4919 struct sock *sk;
4917 struct common_audit_data ad; 4920 struct common_audit_data ad;
4918 struct lsm_network_audit net = {0,}; 4921 struct lsm_network_audit net = {0,};
@@ -5025,7 +5028,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
5025 u32 if_sid; 5028 u32 if_sid;
5026 u32 node_sid; 5029 u32 node_sid;
5027 5030
5028 if (sel_netif_sid(ifindex, &if_sid)) 5031 if (sel_netif_sid(dev_net(outdev), ifindex, &if_sid))
5029 return NF_DROP; 5032 return NF_DROP;
5030 if (avc_has_perm(peer_sid, if_sid, 5033 if (avc_has_perm(peer_sid, if_sid,
5031 SECCLASS_NETIF, NETIF__EGRESS, &ad)) 5034 SECCLASS_NETIF, NETIF__EGRESS, &ad))
@@ -5047,7 +5050,7 @@ static unsigned int selinux_ipv4_postroute(const struct nf_hook_ops *ops,
5047 const struct net_device *out, 5050 const struct net_device *out,
5048 int (*okfn)(struct sk_buff *)) 5051 int (*okfn)(struct sk_buff *))
5049{ 5052{
5050 return selinux_ip_postroute(skb, out->ifindex, PF_INET); 5053 return selinux_ip_postroute(skb, out, PF_INET);
5051} 5054}
5052 5055
5053#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 5056#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -5057,7 +5060,7 @@ static unsigned int selinux_ipv6_postroute(const struct nf_hook_ops *ops,
5057 const struct net_device *out, 5060 const struct net_device *out,
5058 int (*okfn)(struct sk_buff *)) 5061 int (*okfn)(struct sk_buff *))
5059{ 5062{
5060 return selinux_ip_postroute(skb, out->ifindex, PF_INET6); 5063 return selinux_ip_postroute(skb, out, PF_INET6);
5061} 5064}
5062#endif /* IPV6 */ 5065#endif /* IPV6 */
5063 5066