summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorPaul Moore <paul.moore@hp.com>2008-09-05 17:46:07 -0400
committerPaul Moore <paul.moore@hp.com>2008-09-05 17:46:07 -0400
commit787a560389f1c13a80348c44055ab695e6dc0dff (patch)
tree98d2d90e429f5ebfafb0cdad9ebe3934792b0a0a /security
parent082949baf7f5b689102c9952de675692a7b18e49 (diff)
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.c19
-rw-r--r--security/selinux/include/netlabel.h9
-rw-r--r--security/selinux/netlabel.c20
3 files changed, 43 insertions, 5 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 065de8cd752c..a09956da8509 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) {
@@ -4384,6 +4390,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;
@@ -4407,10 +4414,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 89b418392f11..0207bd27bd73 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -106,6 +106,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
@@ -307,7 +325,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;
}