aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/netlabel.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/netlabel.c')
-rw-r--r--security/selinux/netlabel.c75
1 files changed, 45 insertions, 30 deletions
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index 66e013d6f6f6..0fa2be4149e8 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -36,6 +36,33 @@
36#include "security.h" 36#include "security.h"
37 37
38/** 38/**
39 * selinux_netlbl_sidlookup_cached - Cache a SID lookup
40 * @skb: the packet
41 * @secattr: the NetLabel security attributes
42 * @sid: the SID
43 *
44 * Description:
45 * Query the SELinux security server to lookup the correct SID for the given
46 * security attributes. If the query is successful, cache the result to speed
47 * up future lookups. Returns zero on success, negative values on failure.
48 *
49 */
50static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,
51 struct netlbl_lsm_secattr *secattr,
52 u32 *sid)
53{
54 int rc;
55
56 rc = security_netlbl_secattr_to_sid(secattr, sid);
57 if (rc == 0 &&
58 (secattr->flags & NETLBL_SECATTR_CACHEABLE) &&
59 (secattr->flags & NETLBL_SECATTR_CACHE))
60 netlbl_cache_add(skb, secattr);
61
62 return rc;
63}
64
65/**
39 * selinux_netlbl_sock_setsid - Label a socket using the NetLabel mechanism 66 * selinux_netlbl_sock_setsid - Label a socket using the NetLabel mechanism
40 * @sk: the socket to label 67 * @sk: the socket to label
41 * @sid: the SID to use 68 * @sid: the SID to use
@@ -137,14 +164,14 @@ void selinux_netlbl_sk_security_clone(struct sk_security_struct *ssec,
137 * lock as other threads could have access to ssec */ 164 * lock as other threads could have access to ssec */
138 rcu_read_lock(); 165 rcu_read_lock();
139 selinux_netlbl_sk_security_reset(newssec, ssec->sk->sk_family); 166 selinux_netlbl_sk_security_reset(newssec, ssec->sk->sk_family);
140 newssec->sclass = ssec->sclass;
141 rcu_read_unlock(); 167 rcu_read_unlock();
142} 168}
143 169
144/** 170/**
145 * selinux_netlbl_skbuff_getsid - Get the sid of a packet using NetLabel 171 * selinux_netlbl_skbuff_getsid - Get the sid of a packet using NetLabel
146 * @skb: the packet 172 * @skb: the packet
147 * @base_sid: the SELinux SID to use as a context for MLS only attributes 173 * @family: protocol family
174 * @type: NetLabel labeling protocol type
148 * @sid: the SID 175 * @sid: the SID
149 * 176 *
150 * Description: 177 * Description:
@@ -153,7 +180,10 @@ void selinux_netlbl_sk_security_clone(struct sk_security_struct *ssec,
153 * assign to the packet. Returns zero on success, negative values on failure. 180 * assign to the packet. Returns zero on success, negative values on failure.
154 * 181 *
155 */ 182 */
156int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, u32 base_sid, u32 *sid) 183int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
184 u16 family,
185 u32 *type,
186 u32 *sid)
157{ 187{
158 int rc; 188 int rc;
159 struct netlbl_lsm_secattr secattr; 189 struct netlbl_lsm_secattr secattr;
@@ -164,15 +194,12 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, u32 base_sid, u32 *sid)
164 } 194 }
165 195
166 netlbl_secattr_init(&secattr); 196 netlbl_secattr_init(&secattr);
167 rc = netlbl_skbuff_getattr(skb, &secattr); 197 rc = netlbl_skbuff_getattr(skb, family, &secattr);
168 if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) { 198 if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE)
169 rc = security_netlbl_secattr_to_sid(&secattr, base_sid, sid); 199 rc = selinux_netlbl_sidlookup_cached(skb, &secattr, sid);
170 if (rc == 0 && 200 else
171 (secattr.flags & NETLBL_SECATTR_CACHEABLE) &&
172 (secattr.flags & NETLBL_SECATTR_CACHE))
173 netlbl_cache_add(skb, &secattr);
174 } else
175 *sid = SECSID_NULL; 201 *sid = SECSID_NULL;
202 *type = secattr.type;
176 netlbl_secattr_destroy(&secattr); 203 netlbl_secattr_destroy(&secattr);
177 204
178 return rc; 205 return rc;
@@ -190,13 +217,10 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, u32 base_sid, u32 *sid)
190 */ 217 */
191void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock) 218void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock)
192{ 219{
193 struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
194 struct sk_security_struct *sksec = sk->sk_security; 220 struct sk_security_struct *sksec = sk->sk_security;
195 struct netlbl_lsm_secattr secattr; 221 struct netlbl_lsm_secattr secattr;
196 u32 nlbl_peer_sid; 222 u32 nlbl_peer_sid;
197 223
198 sksec->sclass = isec->sclass;
199
200 rcu_read_lock(); 224 rcu_read_lock();
201 225
202 if (sksec->nlbl_state != NLBL_REQUIRE) { 226 if (sksec->nlbl_state != NLBL_REQUIRE) {
@@ -207,9 +231,7 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock)
207 netlbl_secattr_init(&secattr); 231 netlbl_secattr_init(&secattr);
208 if (netlbl_sock_getattr(sk, &secattr) == 0 && 232 if (netlbl_sock_getattr(sk, &secattr) == 0 &&
209 secattr.flags != NETLBL_SECATTR_NONE && 233 secattr.flags != NETLBL_SECATTR_NONE &&
210 security_netlbl_secattr_to_sid(&secattr, 234 security_netlbl_secattr_to_sid(&secattr, &nlbl_peer_sid) == 0)
211 SECINITSID_NETMSG,
212 &nlbl_peer_sid) == 0)
213 sksec->peer_sid = nlbl_peer_sid; 235 sksec->peer_sid = nlbl_peer_sid;
214 netlbl_secattr_destroy(&secattr); 236 netlbl_secattr_destroy(&secattr);
215 237
@@ -234,11 +256,8 @@ int selinux_netlbl_socket_post_create(struct socket *sock)
234{ 256{
235 int rc = 0; 257 int rc = 0;
236 struct sock *sk = sock->sk; 258 struct sock *sk = sock->sk;
237 struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
238 struct sk_security_struct *sksec = sk->sk_security; 259 struct sk_security_struct *sksec = sk->sk_security;
239 260
240 sksec->sclass = isec->sclass;
241
242 rcu_read_lock(); 261 rcu_read_lock();
243 if (sksec->nlbl_state == NLBL_REQUIRE) 262 if (sksec->nlbl_state == NLBL_REQUIRE)
244 rc = selinux_netlbl_sock_setsid(sk, sksec->sid); 263 rc = selinux_netlbl_sock_setsid(sk, sksec->sid);
@@ -292,6 +311,7 @@ int selinux_netlbl_inode_permission(struct inode *inode, int mask)
292 * selinux_netlbl_sock_rcv_skb - Do an inbound access check using NetLabel 311 * selinux_netlbl_sock_rcv_skb - Do an inbound access check using NetLabel
293 * @sksec: the sock's sk_security_struct 312 * @sksec: the sock's sk_security_struct
294 * @skb: the packet 313 * @skb: the packet
314 * @family: protocol family
295 * @ad: the audit data 315 * @ad: the audit data
296 * 316 *
297 * Description: 317 * Description:
@@ -302,6 +322,7 @@ int selinux_netlbl_inode_permission(struct inode *inode, int mask)
302 */ 322 */
303int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, 323int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
304 struct sk_buff *skb, 324 struct sk_buff *skb,
325 u16 family,
305 struct avc_audit_data *ad) 326 struct avc_audit_data *ad)
306{ 327{
307 int rc; 328 int rc;
@@ -313,16 +334,10 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
313 return 0; 334 return 0;
314 335
315 netlbl_secattr_init(&secattr); 336 netlbl_secattr_init(&secattr);
316 rc = netlbl_skbuff_getattr(skb, &secattr); 337 rc = netlbl_skbuff_getattr(skb, family, &secattr);
317 if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) { 338 if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE)
318 rc = security_netlbl_secattr_to_sid(&secattr, 339 rc = selinux_netlbl_sidlookup_cached(skb, &secattr, &nlbl_sid);
319 SECINITSID_NETMSG, 340 else
320 &nlbl_sid);
321 if (rc == 0 &&
322 (secattr.flags & NETLBL_SECATTR_CACHEABLE) &&
323 (secattr.flags & NETLBL_SECATTR_CACHE))
324 netlbl_cache_add(skb, &secattr);
325 } else
326 nlbl_sid = SECINITSID_UNLABELED; 341 nlbl_sid = SECINITSID_UNLABELED;
327 netlbl_secattr_destroy(&secattr); 342 netlbl_secattr_destroy(&secattr);
328 if (rc != 0) 343 if (rc != 0)