diff options
| -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 | ||
