diff options
-rw-r--r-- | security/selinux/hooks.c | 6 | ||||
-rw-r--r-- | security/selinux/include/selinux_netlabel.h | 18 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 45 |
3 files changed, 67 insertions, 2 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 180b26b97d2d..5a66c4c09f7a 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -281,6 +281,8 @@ static int sk_alloc_security(struct sock *sk, int family, gfp_t priority) | |||
281 | ssec->sid = SECINITSID_UNLABELED; | 281 | ssec->sid = SECINITSID_UNLABELED; |
282 | sk->sk_security = ssec; | 282 | sk->sk_security = ssec; |
283 | 283 | ||
284 | selinux_netlbl_sk_security_init(ssec, family); | ||
285 | |||
284 | return 0; | 286 | return 0; |
285 | } | 287 | } |
286 | 288 | ||
@@ -3585,6 +3587,8 @@ static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk) | |||
3585 | 3587 | ||
3586 | newssec->sid = ssec->sid; | 3588 | newssec->sid = ssec->sid; |
3587 | newssec->peer_sid = ssec->peer_sid; | 3589 | newssec->peer_sid = ssec->peer_sid; |
3590 | |||
3591 | selinux_netlbl_sk_clone_security(ssec, newssec); | ||
3588 | } | 3592 | } |
3589 | 3593 | ||
3590 | static void selinux_sk_getsecid(struct sock *sk, u32 *secid) | 3594 | static void selinux_sk_getsecid(struct sock *sk, u32 *secid) |
@@ -3648,6 +3652,8 @@ static void selinux_inet_csk_clone(struct sock *newsk, | |||
3648 | new socket in sync, but we don't have the isec available yet. | 3652 | new socket in sync, but we don't have the isec available yet. |
3649 | So we will wait until sock_graft to do it, by which | 3653 | So we will wait until sock_graft to do it, by which |
3650 | time it will have been created and available. */ | 3654 | time it will have been created and available. */ |
3655 | |||
3656 | selinux_netlbl_sk_security_init(newsksec, req->rsk_ops->family); | ||
3651 | } | 3657 | } |
3652 | 3658 | ||
3653 | static void selinux_req_classify_flow(const struct request_sock *req, | 3659 | static void selinux_req_classify_flow(const struct request_sock *req, |
diff --git a/security/selinux/include/selinux_netlabel.h b/security/selinux/include/selinux_netlabel.h index 88c463eef1e1..d885d880540e 100644 --- a/security/selinux/include/selinux_netlabel.h +++ b/security/selinux/include/selinux_netlabel.h | |||
@@ -39,6 +39,10 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, | |||
39 | struct avc_audit_data *ad); | 39 | struct avc_audit_data *ad); |
40 | u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock); | 40 | u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock); |
41 | u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb); | 41 | u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb); |
42 | void selinux_netlbl_sk_security_init(struct sk_security_struct *ssec, | ||
43 | int family); | ||
44 | void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec, | ||
45 | struct sk_security_struct *newssec); | ||
42 | 46 | ||
43 | int __selinux_netlbl_inode_permission(struct inode *inode, int mask); | 47 | int __selinux_netlbl_inode_permission(struct inode *inode, int mask); |
44 | /** | 48 | /** |
@@ -115,6 +119,20 @@ static inline u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb) | |||
115 | return SECSID_NULL; | 119 | return SECSID_NULL; |
116 | } | 120 | } |
117 | 121 | ||
122 | static inline void selinux_netlbl_sk_security_init( | ||
123 | struct sk_security_struct *ssec, | ||
124 | int family) | ||
125 | { | ||
126 | return; | ||
127 | } | ||
128 | |||
129 | static inline void selinux_netlbl_sk_clone_security( | ||
130 | struct sk_security_struct *ssec, | ||
131 | struct sk_security_struct *newssec) | ||
132 | { | ||
133 | return; | ||
134 | } | ||
135 | |||
118 | static inline int selinux_netlbl_inode_permission(struct inode *inode, | 136 | static inline int selinux_netlbl_inode_permission(struct inode *inode, |
119 | int mask) | 137 | int mask) |
120 | { | 138 | { |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 910afa1ffc31..835b485b2afd 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -2423,6 +2423,45 @@ netlbl_socket_setsid_return: | |||
2423 | } | 2423 | } |
2424 | 2424 | ||
2425 | /** | 2425 | /** |
2426 | * selinux_netlbl_sk_security_init - Setup the NetLabel fields | ||
2427 | * @ssec: the sk_security_struct | ||
2428 | * @family: the socket family | ||
2429 | * | ||
2430 | * Description: | ||
2431 | * Called when a new sk_security_struct is allocated to initialize the NetLabel | ||
2432 | * fields. | ||
2433 | * | ||
2434 | */ | ||
2435 | void selinux_netlbl_sk_security_init(struct sk_security_struct *ssec, | ||
2436 | int family) | ||
2437 | { | ||
2438 | if (family == PF_INET) | ||
2439 | ssec->nlbl_state = NLBL_REQUIRE; | ||
2440 | else | ||
2441 | ssec->nlbl_state = NLBL_UNSET; | ||
2442 | } | ||
2443 | |||
2444 | /** | ||
2445 | * selinux_netlbl_sk_clone_security - Copy the NetLabel fields | ||
2446 | * @ssec: the original sk_security_struct | ||
2447 | * @newssec: the cloned sk_security_struct | ||
2448 | * | ||
2449 | * Description: | ||
2450 | * Clone the NetLabel specific sk_security_struct fields from @ssec to | ||
2451 | * @newssec. | ||
2452 | * | ||
2453 | */ | ||
2454 | void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec, | ||
2455 | struct sk_security_struct *newssec) | ||
2456 | { | ||
2457 | newssec->sclass = ssec->sclass; | ||
2458 | if (ssec->nlbl_state != NLBL_UNSET) | ||
2459 | newssec->nlbl_state = NLBL_REQUIRE; | ||
2460 | else | ||
2461 | newssec->nlbl_state = NLBL_UNSET; | ||
2462 | } | ||
2463 | |||
2464 | /** | ||
2426 | * selinux_netlbl_socket_post_create - Label a socket using NetLabel | 2465 | * selinux_netlbl_socket_post_create - Label a socket using NetLabel |
2427 | * @sock: the socket to label | 2466 | * @sock: the socket to label |
2428 | * @sock_family: the socket family | 2467 | * @sock_family: the socket family |
@@ -2440,10 +2479,11 @@ int selinux_netlbl_socket_post_create(struct socket *sock, | |||
2440 | struct inode_security_struct *isec = SOCK_INODE(sock)->i_security; | 2479 | struct inode_security_struct *isec = SOCK_INODE(sock)->i_security; |
2441 | struct sk_security_struct *sksec = sock->sk->sk_security; | 2480 | struct sk_security_struct *sksec = sock->sk->sk_security; |
2442 | 2481 | ||
2482 | sksec->sclass = isec->sclass; | ||
2483 | |||
2443 | if (sock_family != PF_INET) | 2484 | if (sock_family != PF_INET) |
2444 | return 0; | 2485 | return 0; |
2445 | 2486 | ||
2446 | sksec->sclass = isec->sclass; | ||
2447 | sksec->nlbl_state = NLBL_REQUIRE; | 2487 | sksec->nlbl_state = NLBL_REQUIRE; |
2448 | return selinux_netlbl_socket_setsid(sock, sid); | 2488 | return selinux_netlbl_socket_setsid(sock, sid); |
2449 | } | 2489 | } |
@@ -2463,12 +2503,13 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock) | |||
2463 | struct inode_security_struct *isec = SOCK_INODE(sock)->i_security; | 2503 | struct inode_security_struct *isec = SOCK_INODE(sock)->i_security; |
2464 | struct sk_security_struct *sksec = sk->sk_security; | 2504 | struct sk_security_struct *sksec = sk->sk_security; |
2465 | 2505 | ||
2506 | sksec->sclass = isec->sclass; | ||
2507 | |||
2466 | if (sk->sk_family != PF_INET) | 2508 | if (sk->sk_family != PF_INET) |
2467 | return; | 2509 | return; |
2468 | 2510 | ||
2469 | sksec->nlbl_state = NLBL_REQUIRE; | 2511 | sksec->nlbl_state = NLBL_REQUIRE; |
2470 | sksec->peer_sid = sksec->sid; | 2512 | sksec->peer_sid = sksec->sid; |
2471 | sksec->sclass = isec->sclass; | ||
2472 | 2513 | ||
2473 | /* Try to set the NetLabel on the socket to save time later, if we fail | 2514 | /* Try to set the NetLabel on the socket to save time later, if we fail |
2474 | * here we will pick up the pieces in later calls to | 2515 | * here we will pick up the pieces in later calls to |