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 | |
parent | 99d854d231ce141850b988bdc7e2e7c78f49b03a (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>
-rw-r--r-- | include/net/netlabel.h | 6 | ||||
-rw-r--r-- | net/netlabel/netlabel_kapi.c | 5 | ||||
-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 |
5 files changed, 50 insertions, 9 deletions
diff --git a/include/net/netlabel.h b/include/net/netlabel.h index 5303749b7093..e16db0961265 100644 --- a/include/net/netlabel.h +++ b/include/net/netlabel.h | |||
@@ -382,7 +382,7 @@ int netlbl_sock_getattr(struct sock *sk, | |||
382 | int netlbl_skbuff_getattr(const struct sk_buff *skb, | 382 | int netlbl_skbuff_getattr(const struct sk_buff *skb, |
383 | u16 family, | 383 | u16 family, |
384 | struct netlbl_lsm_secattr *secattr); | 384 | struct netlbl_lsm_secattr *secattr); |
385 | void netlbl_skbuff_err(struct sk_buff *skb, int error); | 385 | void netlbl_skbuff_err(struct sk_buff *skb, int error, int gateway); |
386 | 386 | ||
387 | /* | 387 | /* |
388 | * LSM label mapping cache operations | 388 | * LSM label mapping cache operations |
@@ -454,7 +454,9 @@ static inline int netlbl_skbuff_getattr(const struct sk_buff *skb, | |||
454 | { | 454 | { |
455 | return -ENOSYS; | 455 | return -ENOSYS; |
456 | } | 456 | } |
457 | static inline void netlbl_skbuff_err(struct sk_buff *skb, int error) | 457 | static inline void netlbl_skbuff_err(struct sk_buff *skb, |
458 | int error, | ||
459 | int gateway) | ||
458 | { | 460 | { |
459 | return; | 461 | return; |
460 | } | 462 | } |
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index 6c211fe97782..22faba620e4b 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c | |||
@@ -490,6 +490,7 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb, | |||
490 | * netlbl_skbuff_err - Handle a LSM error on a sk_buff | 490 | * netlbl_skbuff_err - Handle a LSM error on a sk_buff |
491 | * @skb: the packet | 491 | * @skb: the packet |
492 | * @error: the error code | 492 | * @error: the error code |
493 | * @gateway: true if host is acting as a gateway, false otherwise | ||
493 | * | 494 | * |
494 | * Description: | 495 | * Description: |
495 | * Deal with a LSM problem when handling the packet in @skb, typically this is | 496 | * Deal with a LSM problem when handling the packet in @skb, typically this is |
@@ -497,10 +498,10 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb, | |||
497 | * according to the packet's labeling protocol. | 498 | * according to the packet's labeling protocol. |
498 | * | 499 | * |
499 | */ | 500 | */ |
500 | void netlbl_skbuff_err(struct sk_buff *skb, int error) | 501 | void netlbl_skbuff_err(struct sk_buff *skb, int error, int gateway) |
501 | { | 502 | { |
502 | if (CIPSO_V4_OPTEXIST(skb)) | 503 | if (CIPSO_V4_OPTEXIST(skb)) |
503 | cipso_v4_error(skb, error, 0); | 504 | cipso_v4_error(skb, error, gateway); |
504 | } | 505 | } |
505 | 506 | ||
506 | /** | 507 | /** |
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, | |||
4101 | return err; | 4101 | return err; |
4102 | err = avc_has_perm(sk_sid, peer_sid, | 4102 | err = avc_has_perm(sk_sid, peer_sid, |
4103 | SECCLASS_PEER, PEER__RECV, &ad); | 4103 | SECCLASS_PEER, PEER__RECV, &ad); |
4104 | if (err) | ||
4105 | selinux_netlbl_err(skb, err, 0); | ||
4104 | } else { | 4106 | } else { |
4105 | err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad); | 4107 | err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad); |
4106 | if (err) | 4108 | if (err) |
@@ -4156,10 +4158,14 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
4156 | return err; | 4158 | return err; |
4157 | err = selinux_inet_sys_rcv_skb(skb->iif, addrp, family, | 4159 | err = selinux_inet_sys_rcv_skb(skb->iif, addrp, family, |
4158 | peer_sid, &ad); | 4160 | peer_sid, &ad); |
4159 | if (err) | 4161 | if (err) { |
4162 | selinux_netlbl_err(skb, err, 0); | ||
4160 | return err; | 4163 | return err; |
4164 | } | ||
4161 | err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER, | 4165 | err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER, |
4162 | PEER__RECV, &ad); | 4166 | PEER__RECV, &ad); |
4167 | if (err) | ||
4168 | selinux_netlbl_err(skb, err, 0); | ||
4163 | } | 4169 | } |
4164 | 4170 | ||
4165 | if (secmark_active) { | 4171 | if (secmark_active) { |
@@ -4396,6 +4402,7 @@ out: | |||
4396 | static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, | 4402 | static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, |
4397 | u16 family) | 4403 | u16 family) |
4398 | { | 4404 | { |
4405 | int err; | ||
4399 | char *addrp; | 4406 | char *addrp; |
4400 | u32 peer_sid; | 4407 | u32 peer_sid; |
4401 | struct avc_audit_data ad; | 4408 | struct avc_audit_data ad; |
@@ -4419,10 +4426,14 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, | |||
4419 | if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0) | 4426 | if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0) |
4420 | return NF_DROP; | 4427 | return NF_DROP; |
4421 | 4428 | ||
4422 | if (peerlbl_active) | 4429 | if (peerlbl_active) { |
4423 | if (selinux_inet_sys_rcv_skb(ifindex, addrp, family, | 4430 | err = selinux_inet_sys_rcv_skb(ifindex, addrp, family, |
4424 | peer_sid, &ad) != 0) | 4431 | peer_sid, &ad); |
4432 | if (err) { | ||
4433 | selinux_netlbl_err(skb, err, 1); | ||
4425 | return NF_DROP; | 4434 | return NF_DROP; |
4435 | } | ||
4436 | } | ||
4426 | 4437 | ||
4427 | if (secmark_active) | 4438 | if (secmark_active) |
4428 | if (avc_has_perm(peer_sid, skb->secmark, | 4439 | 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 @@ | |||
39 | #ifdef CONFIG_NETLABEL | 39 | #ifdef CONFIG_NETLABEL |
40 | void selinux_netlbl_cache_invalidate(void); | 40 | void selinux_netlbl_cache_invalidate(void); |
41 | 41 | ||
42 | void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway); | ||
43 | |||
42 | void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec, | 44 | void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec, |
43 | int family); | 45 | int family); |
44 | 46 | ||
@@ -63,6 +65,13 @@ static inline void selinux_netlbl_cache_invalidate(void) | |||
63 | return; | 65 | return; |
64 | } | 66 | } |
65 | 67 | ||
68 | static inline void selinux_netlbl_err(struct sk_buff *skb, | ||
69 | int error, | ||
70 | int gateway) | ||
71 | { | ||
72 | return; | ||
73 | } | ||
74 | |||
66 | static inline void selinux_netlbl_sk_security_reset( | 75 | static inline void selinux_netlbl_sk_security_reset( |
67 | struct sk_security_struct *ssec, | 76 | struct sk_security_struct *ssec, |
68 | int family) | 77 | 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) | |||
108 | } | 108 | } |
109 | 109 | ||
110 | /** | 110 | /** |
111 | * selinux_netlbl_err - Handle a NetLabel packet error | ||
112 | * @skb: the packet | ||
113 | * @error: the error code | ||
114 | * @gateway: true if host is acting as a gateway, false otherwise | ||
115 | * | ||
116 | * Description: | ||
117 | * When a packet is dropped due to a call to avc_has_perm() pass the error | ||
118 | * code to the NetLabel subsystem so any protocol specific processing can be | ||
119 | * done. This is safe to call even if you are unsure if NetLabel labeling is | ||
120 | * present on the packet, NetLabel is smart enough to only act when it should. | ||
121 | * | ||
122 | */ | ||
123 | void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway) | ||
124 | { | ||
125 | netlbl_skbuff_err(skb, error, gateway); | ||
126 | } | ||
127 | |||
128 | /** | ||
111 | * selinux_netlbl_sk_security_reset - Reset the NetLabel fields | 129 | * selinux_netlbl_sk_security_reset - Reset the NetLabel fields |
112 | * @ssec: the sk_security_struct | 130 | * @ssec: the sk_security_struct |
113 | * @family: the socket family | 131 | * @family: the socket family |
@@ -289,7 +307,7 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, | |||
289 | return 0; | 307 | return 0; |
290 | 308 | ||
291 | if (nlbl_sid != SECINITSID_UNLABELED) | 309 | if (nlbl_sid != SECINITSID_UNLABELED) |
292 | netlbl_skbuff_err(skb, rc); | 310 | netlbl_skbuff_err(skb, rc, 0); |
293 | return rc; | 311 | return rc; |
294 | } | 312 | } |
295 | 313 | ||