diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/selinux/include/selinux_netlabel.h | 35 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 33 |
2 files changed, 25 insertions, 43 deletions
diff --git a/security/selinux/include/selinux_netlabel.h b/security/selinux/include/selinux_netlabel.h index d885d880540e..d69ec650cdbe 100644 --- a/security/selinux/include/selinux_netlabel.h +++ b/security/selinux/include/selinux_netlabel.h | |||
@@ -43,40 +43,7 @@ void selinux_netlbl_sk_security_init(struct sk_security_struct *ssec, | |||
43 | int family); | 43 | int family); |
44 | void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec, | 44 | void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec, |
45 | struct sk_security_struct *newssec); | 45 | struct sk_security_struct *newssec); |
46 | 46 | int selinux_netlbl_inode_permission(struct inode *inode, int mask); | |
47 | int __selinux_netlbl_inode_permission(struct inode *inode, int mask); | ||
48 | /** | ||
49 | * selinux_netlbl_inode_permission - Verify the socket is NetLabel labeled | ||
50 | * @inode: the file descriptor's inode | ||
51 | * @mask: the permission mask | ||
52 | * | ||
53 | * Description: | ||
54 | * Looks at a file's inode and if it is marked as a socket protected by | ||
55 | * NetLabel then verify that the socket has been labeled, if not try to label | ||
56 | * the socket now with the inode's SID. Returns zero on success, negative | ||
57 | * values on failure. | ||
58 | * | ||
59 | */ | ||
60 | static inline int selinux_netlbl_inode_permission(struct inode *inode, | ||
61 | int mask) | ||
62 | { | ||
63 | int rc = 0; | ||
64 | struct inode_security_struct *isec; | ||
65 | struct sk_security_struct *sksec; | ||
66 | |||
67 | if (!S_ISSOCK(inode->i_mode)) | ||
68 | return 0; | ||
69 | |||
70 | isec = inode->i_security; | ||
71 | sksec = SOCKET_I(inode)->sk->sk_security; | ||
72 | down(&isec->sem); | ||
73 | if (unlikely(sksec->nlbl_state == NLBL_REQUIRE && | ||
74 | (mask & (MAY_WRITE | MAY_APPEND)))) | ||
75 | rc = __selinux_netlbl_inode_permission(inode, mask); | ||
76 | up(&isec->sem); | ||
77 | |||
78 | return rc; | ||
79 | } | ||
80 | #else | 47 | #else |
81 | static inline void selinux_netlbl_cache_invalidate(void) | 48 | static inline void selinux_netlbl_cache_invalidate(void) |
82 | { | 49 | { |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 4f7642c7337e..27ee28ccf266 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -2544,24 +2544,39 @@ u32 selinux_netlbl_inet_conn_request(struct sk_buff *skb, u32 sock_sid) | |||
2544 | } | 2544 | } |
2545 | 2545 | ||
2546 | /** | 2546 | /** |
2547 | * __selinux_netlbl_inode_permission - Label a socket using NetLabel | 2547 | * selinux_netlbl_inode_permission - Verify the socket is NetLabel labeled |
2548 | * @inode: the file descriptor's inode | 2548 | * @inode: the file descriptor's inode |
2549 | * @mask: the permission mask | 2549 | * @mask: the permission mask |
2550 | * | 2550 | * |
2551 | * Description: | 2551 | * Description: |
2552 | * Try to label a socket with the inode's SID using NetLabel. Returns zero on | 2552 | * Looks at a file's inode and if it is marked as a socket protected by |
2553 | * success, negative values on failure. | 2553 | * NetLabel then verify that the socket has been labeled, if not try to label |
2554 | * the socket now with the inode's SID. Returns zero on success, negative | ||
2555 | * values on failure. | ||
2554 | * | 2556 | * |
2555 | */ | 2557 | */ |
2556 | int __selinux_netlbl_inode_permission(struct inode *inode, int mask) | 2558 | int selinux_netlbl_inode_permission(struct inode *inode, int mask) |
2557 | { | 2559 | { |
2558 | int rc; | 2560 | int rc; |
2559 | struct socket *sock = SOCKET_I(inode); | 2561 | struct inode_security_struct *isec; |
2560 | struct sk_security_struct *sksec = sock->sk->sk_security; | 2562 | struct sk_security_struct *sksec; |
2563 | struct socket *sock; | ||
2561 | 2564 | ||
2562 | lock_sock(sock->sk); | 2565 | if (!S_ISSOCK(inode->i_mode)) |
2563 | rc = selinux_netlbl_socket_setsid(sock, sksec->sid); | 2566 | return 0; |
2564 | release_sock(sock->sk); | 2567 | |
2568 | sock = SOCKET_I(inode); | ||
2569 | isec = inode->i_security; | ||
2570 | sksec = sock->sk->sk_security; | ||
2571 | down(&isec->sem); | ||
2572 | if (unlikely(sksec->nlbl_state == NLBL_REQUIRE && | ||
2573 | (mask & (MAY_WRITE | MAY_APPEND)))) { | ||
2574 | lock_sock(sock->sk); | ||
2575 | rc = selinux_netlbl_socket_setsid(sock, sksec->sid); | ||
2576 | release_sock(sock->sk); | ||
2577 | } else | ||
2578 | rc = 0; | ||
2579 | up(&isec->sem); | ||
2565 | 2580 | ||
2566 | return rc; | 2581 | return rc; |
2567 | } | 2582 | } |