mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	selinux: make better use of the nf_hook_state passed to the NF hooks
This patch builds on a previous SELinux/netfilter patch by Florian Westphal and makes better use of the nf_hook_state variable passed into the SELinux/netfilter hooks as well as a number of other small cleanups in the related code. Signed-off-by: Paul Moore <paul@paul-moore.com>
This commit is contained in:
		
							parent
							
								
									cbfcd13be5
								
							
						
					
					
						commit
						1d1e1ded13
					
				
					 1 changed files with 25 additions and 27 deletions
				
			
		| 
						 | 
					@ -5692,38 +5692,38 @@ static int selinux_tun_dev_open(void *security)
 | 
				
			||||||
static unsigned int selinux_ip_forward(void *priv, struct sk_buff *skb,
 | 
					static unsigned int selinux_ip_forward(void *priv, struct sk_buff *skb,
 | 
				
			||||||
				       const struct nf_hook_state *state)
 | 
									       const struct nf_hook_state *state)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct net_device *indev = state->in;
 | 
						int ifindex;
 | 
				
			||||||
	u16 family = state->pf;
 | 
						u16 family;
 | 
				
			||||||
	int err;
 | 
					 | 
				
			||||||
	char *addrp;
 | 
						char *addrp;
 | 
				
			||||||
	u32 peer_sid;
 | 
						u32 peer_sid;
 | 
				
			||||||
	struct common_audit_data ad;
 | 
						struct common_audit_data ad;
 | 
				
			||||||
	struct lsm_network_audit net = {0,};
 | 
						struct lsm_network_audit net = {0,};
 | 
				
			||||||
	u8 secmark_active;
 | 
						int secmark_active, peerlbl_active;
 | 
				
			||||||
	u8 netlbl_active;
 | 
					 | 
				
			||||||
	u8 peerlbl_active;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!selinux_policycap_netpeer())
 | 
						if (!selinux_policycap_netpeer())
 | 
				
			||||||
		return NF_ACCEPT;
 | 
							return NF_ACCEPT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	secmark_active = selinux_secmark_enabled();
 | 
						secmark_active = selinux_secmark_enabled();
 | 
				
			||||||
	netlbl_active = netlbl_enabled();
 | 
					 | 
				
			||||||
	peerlbl_active = selinux_peerlbl_enabled();
 | 
						peerlbl_active = selinux_peerlbl_enabled();
 | 
				
			||||||
	if (!secmark_active && !peerlbl_active)
 | 
						if (!secmark_active && !peerlbl_active)
 | 
				
			||||||
		return NF_ACCEPT;
 | 
							return NF_ACCEPT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						family = state->pf;
 | 
				
			||||||
	if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0)
 | 
						if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0)
 | 
				
			||||||
		return NF_DROP;
 | 
							return NF_DROP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ifindex = state->in->ifindex;
 | 
				
			||||||
	ad.type = LSM_AUDIT_DATA_NET;
 | 
						ad.type = LSM_AUDIT_DATA_NET;
 | 
				
			||||||
	ad.u.net = &net;
 | 
						ad.u.net = &net;
 | 
				
			||||||
	ad.u.net->netif = indev->ifindex;
 | 
						ad.u.net->netif = ifindex;
 | 
				
			||||||
	ad.u.net->family = family;
 | 
						ad.u.net->family = family;
 | 
				
			||||||
	if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
 | 
						if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)
 | 
				
			||||||
		return NF_DROP;
 | 
							return NF_DROP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (peerlbl_active) {
 | 
						if (peerlbl_active) {
 | 
				
			||||||
		err = selinux_inet_sys_rcv_skb(dev_net(indev), indev->ifindex,
 | 
							int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							err = selinux_inet_sys_rcv_skb(state->net, ifindex,
 | 
				
			||||||
					       addrp, family, peer_sid, &ad);
 | 
										       addrp, family, peer_sid, &ad);
 | 
				
			||||||
		if (err) {
 | 
							if (err) {
 | 
				
			||||||
			selinux_netlbl_err(skb, family, err, 1);
 | 
								selinux_netlbl_err(skb, family, err, 1);
 | 
				
			||||||
| 
						 | 
					@ -5737,7 +5737,7 @@ static unsigned int selinux_ip_forward(void *priv, struct sk_buff *skb,
 | 
				
			||||||
				 SECCLASS_PACKET, PACKET__FORWARD_IN, &ad))
 | 
									 SECCLASS_PACKET, PACKET__FORWARD_IN, &ad))
 | 
				
			||||||
			return NF_DROP;
 | 
								return NF_DROP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (netlbl_active)
 | 
						if (netlbl_enabled())
 | 
				
			||||||
		/* we do this in the FORWARD path and not the POST_ROUTING
 | 
							/* we do this in the FORWARD path and not the POST_ROUTING
 | 
				
			||||||
		 * path because we want to make sure we apply the necessary
 | 
							 * path because we want to make sure we apply the necessary
 | 
				
			||||||
		 * labeling before IPsec is applied so we can leverage AH
 | 
							 * labeling before IPsec is applied so we can leverage AH
 | 
				
			||||||
| 
						 | 
					@ -5751,7 +5751,6 @@ static unsigned int selinux_ip_forward(void *priv, struct sk_buff *skb,
 | 
				
			||||||
static unsigned int selinux_ip_output(void *priv, struct sk_buff *skb,
 | 
					static unsigned int selinux_ip_output(void *priv, struct sk_buff *skb,
 | 
				
			||||||
				      const struct nf_hook_state *state)
 | 
									      const struct nf_hook_state *state)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u16 family = state->pf;
 | 
					 | 
				
			||||||
	struct sock *sk;
 | 
						struct sock *sk;
 | 
				
			||||||
	u32 sid;
 | 
						u32 sid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5785,7 +5784,7 @@ static unsigned int selinux_ip_output(void *priv, struct sk_buff *skb,
 | 
				
			||||||
		sid = sksec->sid;
 | 
							sid = sksec->sid;
 | 
				
			||||||
	} else
 | 
						} else
 | 
				
			||||||
		sid = SECINITSID_KERNEL;
 | 
							sid = SECINITSID_KERNEL;
 | 
				
			||||||
	if (selinux_netlbl_skbuff_setsid(skb, family, sid) != 0)
 | 
						if (selinux_netlbl_skbuff_setsid(skb, state->pf, sid) != 0)
 | 
				
			||||||
		return NF_DROP;
 | 
							return NF_DROP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return NF_ACCEPT;
 | 
						return NF_ACCEPT;
 | 
				
			||||||
| 
						 | 
					@ -5793,25 +5792,24 @@ static unsigned int selinux_ip_output(void *priv, struct sk_buff *skb,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
 | 
					static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
 | 
				
			||||||
						int ifindex,
 | 
										const struct nf_hook_state *state)
 | 
				
			||||||
						u16 family)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sock *sk = skb_to_full_sk(skb);
 | 
						struct sock *sk;
 | 
				
			||||||
	struct sk_security_struct *sksec;
 | 
						struct sk_security_struct *sksec;
 | 
				
			||||||
	struct common_audit_data ad;
 | 
						struct common_audit_data ad;
 | 
				
			||||||
	struct lsm_network_audit net = {0,};
 | 
						struct lsm_network_audit net = {0,};
 | 
				
			||||||
	char *addrp;
 | 
					 | 
				
			||||||
	u8 proto;
 | 
						u8 proto;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sk == NULL)
 | 
						if (state->sk == NULL)
 | 
				
			||||||
		return NF_ACCEPT;
 | 
							return NF_ACCEPT;
 | 
				
			||||||
 | 
						sk = skb_to_full_sk(skb);
 | 
				
			||||||
	sksec = sk->sk_security;
 | 
						sksec = sk->sk_security;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ad.type = LSM_AUDIT_DATA_NET;
 | 
						ad.type = LSM_AUDIT_DATA_NET;
 | 
				
			||||||
	ad.u.net = &net;
 | 
						ad.u.net = &net;
 | 
				
			||||||
	ad.u.net->netif = ifindex;
 | 
						ad.u.net->netif = state->out->ifindex;
 | 
				
			||||||
	ad.u.net->family = family;
 | 
						ad.u.net->family = state->pf;
 | 
				
			||||||
	if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto))
 | 
						if (selinux_parse_skb(skb, &ad, NULL, 0, &proto))
 | 
				
			||||||
		return NF_DROP;
 | 
							return NF_DROP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (selinux_secmark_enabled())
 | 
						if (selinux_secmark_enabled())
 | 
				
			||||||
| 
						 | 
					@ -5830,24 +5828,22 @@ static unsigned int selinux_ip_postroute(void *priv,
 | 
				
			||||||
					 struct sk_buff *skb,
 | 
										 struct sk_buff *skb,
 | 
				
			||||||
					 const struct nf_hook_state *state)
 | 
										 const struct nf_hook_state *state)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const struct net_device *outdev = state->out;
 | 
						u16 family;
 | 
				
			||||||
	u16 family = state->pf;
 | 
					 | 
				
			||||||
	u32 secmark_perm;
 | 
						u32 secmark_perm;
 | 
				
			||||||
	u32 peer_sid;
 | 
						u32 peer_sid;
 | 
				
			||||||
	int ifindex = outdev->ifindex;
 | 
						int ifindex;
 | 
				
			||||||
	struct sock *sk;
 | 
						struct sock *sk;
 | 
				
			||||||
	struct common_audit_data ad;
 | 
						struct common_audit_data ad;
 | 
				
			||||||
	struct lsm_network_audit net = {0,};
 | 
						struct lsm_network_audit net = {0,};
 | 
				
			||||||
	char *addrp;
 | 
						char *addrp;
 | 
				
			||||||
	u8 secmark_active;
 | 
						int secmark_active, peerlbl_active;
 | 
				
			||||||
	u8 peerlbl_active;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* If any sort of compatibility mode is enabled then handoff processing
 | 
						/* If any sort of compatibility mode is enabled then handoff processing
 | 
				
			||||||
	 * to the selinux_ip_postroute_compat() function to deal with the
 | 
						 * to the selinux_ip_postroute_compat() function to deal with the
 | 
				
			||||||
	 * special handling.  We do this in an attempt to keep this function
 | 
						 * special handling.  We do this in an attempt to keep this function
 | 
				
			||||||
	 * as fast and as clean as possible. */
 | 
						 * as fast and as clean as possible. */
 | 
				
			||||||
	if (!selinux_policycap_netpeer())
 | 
						if (!selinux_policycap_netpeer())
 | 
				
			||||||
		return selinux_ip_postroute_compat(skb, ifindex, family);
 | 
							return selinux_ip_postroute_compat(skb, state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	secmark_active = selinux_secmark_enabled();
 | 
						secmark_active = selinux_secmark_enabled();
 | 
				
			||||||
	peerlbl_active = selinux_peerlbl_enabled();
 | 
						peerlbl_active = selinux_peerlbl_enabled();
 | 
				
			||||||
| 
						 | 
					@ -5873,6 +5869,7 @@ static unsigned int selinux_ip_postroute(void *priv,
 | 
				
			||||||
		return NF_ACCEPT;
 | 
							return NF_ACCEPT;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						family = state->pf;
 | 
				
			||||||
	if (sk == NULL) {
 | 
						if (sk == NULL) {
 | 
				
			||||||
		/* Without an associated socket the packet is either coming
 | 
							/* Without an associated socket the packet is either coming
 | 
				
			||||||
		 * from the kernel or it is being forwarded; check the packet
 | 
							 * from the kernel or it is being forwarded; check the packet
 | 
				
			||||||
| 
						 | 
					@ -5933,6 +5930,7 @@ static unsigned int selinux_ip_postroute(void *priv,
 | 
				
			||||||
		secmark_perm = PACKET__SEND;
 | 
							secmark_perm = PACKET__SEND;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ifindex = state->out->ifindex;
 | 
				
			||||||
	ad.type = LSM_AUDIT_DATA_NET;
 | 
						ad.type = LSM_AUDIT_DATA_NET;
 | 
				
			||||||
	ad.u.net = &net;
 | 
						ad.u.net = &net;
 | 
				
			||||||
	ad.u.net->netif = ifindex;
 | 
						ad.u.net->netif = ifindex;
 | 
				
			||||||
| 
						 | 
					@ -5950,7 +5948,7 @@ static unsigned int selinux_ip_postroute(void *priv,
 | 
				
			||||||
		u32 if_sid;
 | 
							u32 if_sid;
 | 
				
			||||||
		u32 node_sid;
 | 
							u32 node_sid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (sel_netif_sid(dev_net(outdev), ifindex, &if_sid))
 | 
							if (sel_netif_sid(state->net, ifindex, &if_sid))
 | 
				
			||||||
			return NF_DROP;
 | 
								return NF_DROP;
 | 
				
			||||||
		if (avc_has_perm(&selinux_state,
 | 
							if (avc_has_perm(&selinux_state,
 | 
				
			||||||
				 peer_sid, if_sid,
 | 
									 peer_sid, if_sid,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue