diff options
| author | Paul Moore <paul.moore@hp.com> | 2008-10-10 10:16:31 -0400 | 
|---|---|---|
| committer | Paul Moore <paul.moore@hp.com> | 2008-10-10 10:16:31 -0400 | 
| commit | dfaebe9825ff34983778f287101bc5f3bce00640 (patch) | |
| tree | 4dccdcdcecd57fc8bfc083ff30d9e0ecb2e7ecba /security | |
| parent | 99d854d231ce141850b988bdc7e2e7c78f49b03a (diff) | |
| download | linux-dfaebe9825ff34983778f287101bc5f3bce00640.tar.bz2 | |
selinux: Fix missing calls to netlbl_skbuff_err()
At some point I think I messed up and dropped the calls to netlbl_skbuff_err()
which are necessary for CIPSO to send error notifications to remote systems.
This patch re-introduces the error handling calls into the SELinux code.
Signed-off-by: Paul Moore <paul.moore@hp.com>
Acked-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security')
| -rw-r--r-- | security/selinux/hooks.c | 19 | ||||
| -rw-r--r-- | security/selinux/include/netlabel.h | 9 | ||||
| -rw-r--r-- | security/selinux/netlabel.c | 20 | 
3 files changed, 43 insertions, 5 deletions
| diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b520667a24be..a91146a6b37d 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4101,6 +4101,8 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,  			return err;  		err = avc_has_perm(sk_sid, peer_sid,  				   SECCLASS_PEER, PEER__RECV, &ad); +		if (err) +			selinux_netlbl_err(skb, err, 0);  	} else {  		err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);  		if (err) @@ -4156,10 +4158,14 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)  			return err;  		err = selinux_inet_sys_rcv_skb(skb->iif, addrp, family,  					       peer_sid, &ad); -		if (err) +		if (err) { +			selinux_netlbl_err(skb, err, 0);  			return err; +		}  		err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER,  				   PEER__RECV, &ad); +		if (err) +			selinux_netlbl_err(skb, err, 0);  	}  	if (secmark_active) { @@ -4396,6 +4402,7 @@ out:  static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,  				       u16 family)  { +	int err;  	char *addrp;  	u32 peer_sid;  	struct avc_audit_data ad; @@ -4419,10 +4426,14 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,  	if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0)  		return NF_DROP; -	if (peerlbl_active) -		if (selinux_inet_sys_rcv_skb(ifindex, addrp, family, -					     peer_sid, &ad) != 0) +	if (peerlbl_active) { +		err = selinux_inet_sys_rcv_skb(ifindex, addrp, family, +					       peer_sid, &ad); +		if (err) { +			selinux_netlbl_err(skb, err, 1);  			return NF_DROP; +		} +	}  	if (secmark_active)  		if (avc_has_perm(peer_sid, skb->secmark, diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h index 487a7d81fe20..d4e3ac8a7fbf 100644 --- a/security/selinux/include/netlabel.h +++ b/security/selinux/include/netlabel.h @@ -39,6 +39,8 @@  #ifdef CONFIG_NETLABEL  void selinux_netlbl_cache_invalidate(void); +void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway); +  void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec,  				      int family); @@ -63,6 +65,13 @@ static inline void selinux_netlbl_cache_invalidate(void)  	return;  } +static inline void selinux_netlbl_err(struct sk_buff *skb, +				      int error, +				      int gateway) +{ +	return; +} +  static inline void selinux_netlbl_sk_security_reset(  					       struct sk_security_struct *ssec,  					       int family) diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index b9ce5fcf3432..4053f7fc95fb 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -108,6 +108,24 @@ void selinux_netlbl_cache_invalidate(void)  }  /** + * selinux_netlbl_err - Handle a NetLabel packet error + * @skb: the packet + * @error: the error code + * @gateway: true if host is acting as a gateway, false otherwise + * + * Description: + * When a packet is dropped due to a call to avc_has_perm() pass the error + * code to the NetLabel subsystem so any protocol specific processing can be + * done.  This is safe to call even if you are unsure if NetLabel labeling is + * present on the packet, NetLabel is smart enough to only act when it should. + * + */ +void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway) +{ +	netlbl_skbuff_err(skb, error, gateway); +} + +/**   * selinux_netlbl_sk_security_reset - Reset the NetLabel fields   * @ssec: the sk_security_struct   * @family: the socket family @@ -289,7 +307,7 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,  		return 0;  	if (nlbl_sid != SECINITSID_UNLABELED) -		netlbl_skbuff_err(skb, rc); +		netlbl_skbuff_err(skb, rc, 0);  	return rc;  } |