Blame view
security/selinux/netlabel.c
15.8 KB
1ccea77e2 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
5778eabd9 SELinux: extract ... |
2 3 4 5 6 7 |
/* * SELinux NetLabel Support * * This file provides the necessary glue to tie NetLabel into the SELinux * subsystem. * |
82c21bfab doc: Update the e... |
8 |
* Author: Paul Moore <paul@paul-moore.com> |
5778eabd9 SELinux: extract ... |
9 10 11 |
*/ /* |
948bf85c1 netlabel: Add fun... |
12 |
* (c) Copyright Hewlett-Packard Development Company, L.P., 2007, 2008 |
5778eabd9 SELinux: extract ... |
13 14 15 16 |
*/ #include <linux/spinlock.h> #include <linux/rcupdate.h> |
5a0e3ad6a include cleanup: ... |
17 |
#include <linux/gfp.h> |
014ab19a6 selinux: Set sock... |
18 19 |
#include <linux/ip.h> #include <linux/ipv6.h> |
5778eabd9 SELinux: extract ... |
20 21 |
#include <net/sock.h> #include <net/netlabel.h> |
014ab19a6 selinux: Set sock... |
22 23 |
#include <net/ip.h> #include <net/ipv6.h> |
5778eabd9 SELinux: extract ... |
24 25 26 |
#include "objsec.h" #include "security.h" |
d4ee4231a selinux: selinux/... |
27 |
#include "netlabel.h" |
5778eabd9 SELinux: extract ... |
28 29 |
/** |
5dbe1eb0c SELinux: Allow Ne... |
30 31 32 33 34 35 36 37 38 39 40 41 |
* selinux_netlbl_sidlookup_cached - Cache a SID lookup * @skb: the packet * @secattr: the NetLabel security attributes * @sid: the SID * * Description: * Query the SELinux security server to lookup the correct SID for the given * security attributes. If the query is successful, cache the result to speed * up future lookups. Returns zero on success, negative values on failure. * */ static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb, |
4fee5242b calipso: Add a la... |
42 |
u16 family, |
5dbe1eb0c SELinux: Allow Ne... |
43 44 45 46 |
struct netlbl_lsm_secattr *secattr, u32 *sid) { int rc; |
aa8e712ce selinux: wrap glo... |
47 |
rc = security_netlbl_secattr_to_sid(&selinux_state, secattr, sid); |
5dbe1eb0c SELinux: Allow Ne... |
48 49 50 |
if (rc == 0 && (secattr->flags & NETLBL_SECATTR_CACHEABLE) && (secattr->flags & NETLBL_SECATTR_CACHE)) |
4fee5242b calipso: Add a la... |
51 |
netlbl_cache_add(skb, family, secattr); |
5dbe1eb0c SELinux: Allow Ne... |
52 53 54 55 56 |
return rc; } /** |
6c5b3fc01 selinux: Cache Ne... |
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
* selinux_netlbl_sock_genattr - Generate the NetLabel socket secattr * @sk: the socket * * Description: * Generate the NetLabel security attributes for a socket, making full use of * the socket's attribute cache. Returns a pointer to the security attributes * on success, NULL on failure. * */ static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk) { int rc; struct sk_security_struct *sksec = sk->sk_security; struct netlbl_lsm_secattr *secattr; if (sksec->nlbl_secattr != NULL) return sksec->nlbl_secattr; secattr = netlbl_secattr_alloc(GFP_ATOMIC); if (secattr == NULL) return NULL; |
aa8e712ce selinux: wrap glo... |
78 79 |
rc = security_netlbl_sid_to_secattr(&selinux_state, sksec->sid, secattr); |
6c5b3fc01 selinux: Cache Ne... |
80 81 82 83 84 85 86 87 88 89 |
if (rc != 0) { netlbl_secattr_free(secattr); return NULL; } sksec->nlbl_secattr = secattr; return secattr; } /** |
050d032b2 selinux: ensure t... |
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
* selinux_netlbl_sock_getattr - Get the cached NetLabel secattr * @sk: the socket * @sid: the SID * * Query the socket's cached secattr and if the SID matches the cached value * return the cache, otherwise return NULL. * */ static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr( const struct sock *sk, u32 sid) { struct sk_security_struct *sksec = sk->sk_security; struct netlbl_lsm_secattr *secattr = sksec->nlbl_secattr; if (secattr == NULL) return NULL; if ((secattr->flags & NETLBL_SECATTR_SECID) && (secattr->attr.secid == sid)) return secattr; return NULL; } /** |
5778eabd9 SELinux: extract ... |
116 117 118 119 120 121 122 123 124 125 126 127 |
* selinux_netlbl_cache_invalidate - Invalidate the NetLabel cache * * Description: * Invalidate the NetLabel security attribute mapping cache. * */ void selinux_netlbl_cache_invalidate(void) { netlbl_cache_invalidate(); } /** |
dfaebe982 selinux: Fix miss... |
128 129 130 131 132 133 134 135 136 137 138 139 |
* selinux_netlbl_err - Handle a NetLabel packet error * @skb: the packet * @error: the error code * @gateway: true if host is acting as a gateway, false otherwise * * Description: * When a packet is dropped due to a call to avc_has_perm() pass the error * code to the NetLabel subsystem so any protocol specific processing can be * done. This is safe to call even if you are unsure if NetLabel labeling is * present on the packet, NetLabel is smart enough to only act when it should. * */ |
a04e71f63 netlabel: Pass a ... |
140 |
void selinux_netlbl_err(struct sk_buff *skb, u16 family, int error, int gateway) |
dfaebe982 selinux: Fix miss... |
141 |
{ |
a04e71f63 netlabel: Pass a ... |
142 |
netlbl_skbuff_err(skb, family, error, gateway); |
dfaebe982 selinux: Fix miss... |
143 144 145 |
} /** |
6c5b3fc01 selinux: Cache Ne... |
146 |
* selinux_netlbl_sk_security_free - Free the NetLabel fields |
dd3e7836b selinux: always c... |
147 |
* @sksec: the sk_security_struct |
6c5b3fc01 selinux: Cache Ne... |
148 149 150 151 152 |
* * Description: * Free all of the memory in the NetLabel fields of a sk_security_struct. * */ |
dd3e7836b selinux: always c... |
153 |
void selinux_netlbl_sk_security_free(struct sk_security_struct *sksec) |
6c5b3fc01 selinux: Cache Ne... |
154 |
{ |
dd3e7836b selinux: always c... |
155 156 |
if (sksec->nlbl_secattr != NULL) netlbl_secattr_free(sksec->nlbl_secattr); |
6c5b3fc01 selinux: Cache Ne... |
157 158 159 |
} /** |
5778eabd9 SELinux: extract ... |
160 |
* selinux_netlbl_sk_security_reset - Reset the NetLabel fields |
dd3e7836b selinux: always c... |
161 |
* @sksec: the sk_security_struct |
5778eabd9 SELinux: extract ... |
162 163 164 165 |
* @family: the socket family * * Description: * Called when the NetLabel state of a sk_security_struct needs to be reset. |
25985edce Fix common misspe... |
166 |
* The caller is responsible for all the NetLabel sk_security_struct locking. |
5778eabd9 SELinux: extract ... |
167 168 |
* */ |
dd3e7836b selinux: always c... |
169 |
void selinux_netlbl_sk_security_reset(struct sk_security_struct *sksec) |
5778eabd9 SELinux: extract ... |
170 |
{ |
dd3e7836b selinux: always c... |
171 |
sksec->nlbl_state = NLBL_UNSET; |
5778eabd9 SELinux: extract ... |
172 173 174 |
} /** |
5778eabd9 SELinux: extract ... |
175 176 |
* selinux_netlbl_skbuff_getsid - Get the sid of a packet using NetLabel * @skb: the packet |
75e22910c NetLabel: Add IP ... |
177 |
* @family: protocol family |
220deb966 SELinux: Better i... |
178 |
* @type: NetLabel labeling protocol type |
5778eabd9 SELinux: extract ... |
179 180 181 182 183 184 185 186 |
* @sid: the SID * * Description: * Call the NetLabel mechanism to get the security attributes of the given * packet and use those attributes to determine the correct context/SID to * assign to the packet. Returns zero on success, negative values on failure. * */ |
75e22910c NetLabel: Add IP ... |
187 188 |
int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, u16 family, |
220deb966 SELinux: Better i... |
189 |
u32 *type, |
75e22910c NetLabel: Add IP ... |
190 |
u32 *sid) |
5778eabd9 SELinux: extract ... |
191 192 193 |
{ int rc; struct netlbl_lsm_secattr secattr; |
23bcdc1ad SELinux: enable d... |
194 195 196 197 |
if (!netlbl_enabled()) { *sid = SECSID_NULL; return 0; } |
5778eabd9 SELinux: extract ... |
198 |
netlbl_secattr_init(&secattr); |
75e22910c NetLabel: Add IP ... |
199 |
rc = netlbl_skbuff_getattr(skb, family, &secattr); |
5dbe1eb0c SELinux: Allow Ne... |
200 |
if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) |
4fee5242b calipso: Add a la... |
201 202 |
rc = selinux_netlbl_sidlookup_cached(skb, family, &secattr, sid); |
5dbe1eb0c SELinux: Allow Ne... |
203 |
else |
5778eabd9 SELinux: extract ... |
204 |
*sid = SECSID_NULL; |
220deb966 SELinux: Better i... |
205 |
*type = secattr.type; |
5778eabd9 SELinux: extract ... |
206 207 208 209 210 211 |
netlbl_secattr_destroy(&secattr); return rc; } /** |
948bf85c1 netlabel: Add fun... |
212 213 214 215 216 217 218 |
* selinux_netlbl_skbuff_setsid - Set the NetLabel on a packet given a sid * @skb: the packet * @family: protocol family * @sid: the SID * * Description * Call the NetLabel mechanism to set the label of a packet using @sid. |
af901ca18 tree-wide: fix as... |
219 |
* Returns zero on success, negative values on failure. |
948bf85c1 netlabel: Add fun... |
220 221 222 223 224 225 226 |
* */ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, u16 family, u32 sid) { int rc; |
6c5b3fc01 selinux: Cache Ne... |
227 228 |
struct netlbl_lsm_secattr secattr_storage; struct netlbl_lsm_secattr *secattr = NULL; |
948bf85c1 netlabel: Add fun... |
229 230 231 232 |
struct sock *sk; /* if this is a locally generated packet check to see if it is already * being labeled by it's parent socket, if it is just exit */ |
54abc686c net: add skb_to_f... |
233 |
sk = skb_to_full_sk(skb); |
948bf85c1 netlabel: Add fun... |
234 235 |
if (sk != NULL) { struct sk_security_struct *sksec = sk->sk_security; |
d452930fd selinux: Add SCTP... |
236 |
|
948bf85c1 netlabel: Add fun... |
237 238 |
if (sksec->nlbl_state != NLBL_REQSKB) return 0; |
050d032b2 selinux: ensure t... |
239 |
secattr = selinux_netlbl_sock_getattr(sk, sid); |
6c5b3fc01 selinux: Cache Ne... |
240 241 242 243 |
} if (secattr == NULL) { secattr = &secattr_storage; netlbl_secattr_init(secattr); |
aa8e712ce selinux: wrap glo... |
244 245 |
rc = security_netlbl_sid_to_secattr(&selinux_state, sid, secattr); |
6c5b3fc01 selinux: Cache Ne... |
246 247 |
if (rc != 0) goto skbuff_setsid_return; |
948bf85c1 netlabel: Add fun... |
248 |
} |
6c5b3fc01 selinux: Cache Ne... |
249 |
rc = netlbl_skbuff_setattr(skb, family, secattr); |
948bf85c1 netlabel: Add fun... |
250 251 |
skbuff_setsid_return: |
6c5b3fc01 selinux: Cache Ne... |
252 253 |
if (secattr == &secattr_storage) netlbl_secattr_destroy(secattr); |
948bf85c1 netlabel: Add fun... |
254 255 256 257 |
return rc; } /** |
d452930fd selinux: Add SCTP... |
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 |
* selinux_netlbl_sctp_assoc_request - Label an incoming sctp association. * @ep: incoming association endpoint. * @skb: the packet. * * Description: * A new incoming connection is represented by @ep, ...... * Returns zero on success, negative values on failure. * */ int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep, struct sk_buff *skb) { int rc; struct netlbl_lsm_secattr secattr; struct sk_security_struct *sksec = ep->base.sk->sk_security; |
d452930fd selinux: Add SCTP... |
273 |
struct sockaddr_in addr4; |
d452930fd selinux: Add SCTP... |
274 |
struct sockaddr_in6 addr6; |
d452930fd selinux: Add SCTP... |
275 276 277 278 279 280 |
if (ep->base.sk->sk_family != PF_INET && ep->base.sk->sk_family != PF_INET6) return 0; netlbl_secattr_init(&secattr); |
aa8e712ce selinux: wrap glo... |
281 282 |
rc = security_netlbl_sid_to_secattr(&selinux_state, ep->secid, &secattr); |
d452930fd selinux: Add SCTP... |
283 284 285 286 287 288 289 290 291 |
if (rc != 0) goto assoc_request_return; /* Move skb hdr address info to a struct sockaddr and then call * netlbl_conn_setattr(). */ if (ip_hdr(skb)->version == 4) { addr4.sin_family = AF_INET; addr4.sin_addr.s_addr = ip_hdr(skb)->saddr; |
98bbbb76f selinux: avoid un... |
292 293 |
rc = netlbl_conn_setattr(ep->base.sk, (void *)&addr4, &secattr); } else if (IS_ENABLED(CONFIG_IPV6) && ip_hdr(skb)->version == 6) { |
d452930fd selinux: Add SCTP... |
294 295 |
addr6.sin6_family = AF_INET6; addr6.sin6_addr = ipv6_hdr(skb)->saddr; |
98bbbb76f selinux: avoid un... |
296 297 298 |
rc = netlbl_conn_setattr(ep->base.sk, (void *)&addr6, &secattr); } else { rc = -EAFNOSUPPORT; |
d452930fd selinux: Add SCTP... |
299 |
} |
d452930fd selinux: Add SCTP... |
300 301 302 303 304 305 306 307 308 |
if (rc == 0) sksec->nlbl_state = NLBL_LABELED; assoc_request_return: netlbl_secattr_destroy(&secattr); return rc; } /** |
389fb800a netlabel: Label i... |
309 310 |
* selinux_netlbl_inet_conn_request - Label an incoming stream connection * @req: incoming connection request socket |
5778eabd9 SELinux: extract ... |
311 312 |
* * Description: |
389fb800a netlabel: Label i... |
313 314 315 316 |
* A new incoming connection request is represented by @req, we need to label * the new request_sock here and the stack will ensure the on-the-wire label * will get preserved when a full sock is created once the connection handshake * is complete. Returns zero on success, negative values on failure. |
5778eabd9 SELinux: extract ... |
317 318 |
* */ |
389fb800a netlabel: Label i... |
319 |
int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family) |
5778eabd9 SELinux: extract ... |
320 |
{ |
014ab19a6 selinux: Set sock... |
321 |
int rc; |
389fb800a netlabel: Label i... |
322 |
struct netlbl_lsm_secattr secattr; |
014ab19a6 selinux: Set sock... |
323 |
|
e1adea927 calipso: Allow re... |
324 |
if (family != PF_INET && family != PF_INET6) |
389fb800a netlabel: Label i... |
325 |
return 0; |
014ab19a6 selinux: Set sock... |
326 |
|
389fb800a netlabel: Label i... |
327 |
netlbl_secattr_init(&secattr); |
aa8e712ce selinux: wrap glo... |
328 329 |
rc = security_netlbl_sid_to_secattr(&selinux_state, req->secid, &secattr); |
389fb800a netlabel: Label i... |
330 331 332 333 334 335 |
if (rc != 0) goto inet_conn_request_return; rc = netlbl_req_setattr(req, &secattr); inet_conn_request_return: netlbl_secattr_destroy(&secattr); return rc; |
5778eabd9 SELinux: extract ... |
336 337 338 |
} /** |
389fb800a netlabel: Label i... |
339 340 |
* selinux_netlbl_inet_csk_clone - Initialize the newly created sock * @sk: the new sock |
5778eabd9 SELinux: extract ... |
341 342 |
* * Description: |
389fb800a netlabel: Label i... |
343 344 345 |
* A new connection has been established using @sk, we've already labeled the * socket via the request_sock struct in selinux_netlbl_inet_conn_request() but * we need to set the NetLabel state here since we now have a sock structure. |
5778eabd9 SELinux: extract ... |
346 347 |
* */ |
389fb800a netlabel: Label i... |
348 |
void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family) |
5778eabd9 SELinux: extract ... |
349 |
{ |
389fb800a netlabel: Label i... |
350 351 352 353 354 355 |
struct sk_security_struct *sksec = sk->sk_security; if (family == PF_INET) sksec->nlbl_state = NLBL_LABELED; else sksec->nlbl_state = NLBL_UNSET; |
5778eabd9 SELinux: extract ... |
356 357 358 |
} /** |
d452930fd selinux: Add SCTP... |
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 |
* selinux_netlbl_sctp_sk_clone - Copy state to the newly created sock * @sk: current sock * @newsk: the new sock * * Description: * Called whenever a new socket is created by accept(2) or sctp_peeloff(3). */ void selinux_netlbl_sctp_sk_clone(struct sock *sk, struct sock *newsk) { struct sk_security_struct *sksec = sk->sk_security; struct sk_security_struct *newsksec = newsk->sk_security; newsksec->nlbl_state = sksec->nlbl_state; } /** |
389fb800a netlabel: Label i... |
375 376 377 |
* selinux_netlbl_socket_post_create - Label a socket using NetLabel * @sock: the socket to label * @family: protocol family |
5778eabd9 SELinux: extract ... |
378 379 |
* * Description: |
389fb800a netlabel: Label i... |
380 381 |
* Attempt to label a socket using the NetLabel mechanism using the given * SID. Returns zero values on success, negative values on failure. |
5778eabd9 SELinux: extract ... |
382 383 |
* */ |
389fb800a netlabel: Label i... |
384 |
int selinux_netlbl_socket_post_create(struct sock *sk, u16 family) |
5778eabd9 SELinux: extract ... |
385 386 |
{ int rc; |
389fb800a netlabel: Label i... |
387 388 |
struct sk_security_struct *sksec = sk->sk_security; struct netlbl_lsm_secattr *secattr; |
5778eabd9 SELinux: extract ... |
389 |
|
ceba1832b calipso: Set the ... |
390 |
if (family != PF_INET && family != PF_INET6) |
5778eabd9 SELinux: extract ... |
391 |
return 0; |
f74af6e81 SELinux: Correct ... |
392 |
|
389fb800a netlabel: Label i... |
393 394 395 396 397 398 399 400 401 402 |
secattr = selinux_netlbl_sock_genattr(sk); if (secattr == NULL) return -ENOMEM; rc = netlbl_sock_setattr(sk, family, secattr); switch (rc) { case 0: sksec->nlbl_state = NLBL_LABELED; break; case -EDESTADDRREQ: sksec->nlbl_state = NLBL_REQSKB; |
f74af6e81 SELinux: Correct ... |
403 |
rc = 0; |
389fb800a netlabel: Label i... |
404 405 |
break; } |
5778eabd9 SELinux: extract ... |
406 407 408 409 410 411 412 413 |
return rc; } /** * selinux_netlbl_sock_rcv_skb - Do an inbound access check using NetLabel * @sksec: the sock's sk_security_struct * @skb: the packet |
75e22910c NetLabel: Add IP ... |
414 |
* @family: protocol family |
5778eabd9 SELinux: extract ... |
415 416 417 418 419 420 421 422 423 424 |
* @ad: the audit data * * Description: * Fetch the NetLabel security attributes from @skb and perform an access check * against the receiving socket. Returns zero on success, negative values on * error. * */ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, struct sk_buff *skb, |
75e22910c NetLabel: Add IP ... |
425 |
u16 family, |
2bf496903 SELinux: Convert ... |
426 |
struct common_audit_data *ad) |
5778eabd9 SELinux: extract ... |
427 428 |
{ int rc; |
f36158c41 SELinux: use SECI... |
429 430 431 |
u32 nlbl_sid; u32 perm; struct netlbl_lsm_secattr secattr; |
5778eabd9 SELinux: extract ... |
432 |
|
23bcdc1ad SELinux: enable d... |
433 434 |
if (!netlbl_enabled()) return 0; |
f36158c41 SELinux: use SECI... |
435 |
netlbl_secattr_init(&secattr); |
75e22910c NetLabel: Add IP ... |
436 |
rc = netlbl_skbuff_getattr(skb, family, &secattr); |
5dbe1eb0c SELinux: Allow Ne... |
437 |
if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) |
4fee5242b calipso: Add a la... |
438 439 |
rc = selinux_netlbl_sidlookup_cached(skb, family, &secattr, &nlbl_sid); |
5dbe1eb0c SELinux: Allow Ne... |
440 |
else |
f36158c41 SELinux: use SECI... |
441 442 |
nlbl_sid = SECINITSID_UNLABELED; netlbl_secattr_destroy(&secattr); |
5778eabd9 SELinux: extract ... |
443 444 |
if (rc != 0) return rc; |
8d9107e8c Revert "SELinux: ... |
445 |
|
5778eabd9 SELinux: extract ... |
446 447 |
switch (sksec->sclass) { case SECCLASS_UDP_SOCKET: |
f36158c41 SELinux: use SECI... |
448 |
perm = UDP_SOCKET__RECVFROM; |
5778eabd9 SELinux: extract ... |
449 450 |
break; case SECCLASS_TCP_SOCKET: |
f36158c41 SELinux: use SECI... |
451 |
perm = TCP_SOCKET__RECVFROM; |
5778eabd9 SELinux: extract ... |
452 453 |
break; default: |
f36158c41 SELinux: use SECI... |
454 |
perm = RAWIP_SOCKET__RECVFROM; |
5778eabd9 SELinux: extract ... |
455 |
} |
6b6bc6205 selinux: wrap AVC... |
456 457 |
rc = avc_has_perm(&selinux_state, sksec->sid, nlbl_sid, sksec->sclass, perm, ad); |
5778eabd9 SELinux: extract ... |
458 459 |
if (rc == 0) return 0; |
f36158c41 SELinux: use SECI... |
460 |
if (nlbl_sid != SECINITSID_UNLABELED) |
a04e71f63 netlabel: Pass a ... |
461 |
netlbl_skbuff_err(skb, family, rc, 0); |
5778eabd9 SELinux: extract ... |
462 463 464 465 |
return rc; } /** |
1f440c99d netlabel: Prevent... |
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 |
* selinux_netlbl_option - Is this a NetLabel option * @level: the socket level or protocol * @optname: the socket option name * * Description: * Returns true if @level and @optname refer to a NetLabel option. * Helper for selinux_netlbl_socket_setsockopt(). */ static inline int selinux_netlbl_option(int level, int optname) { return (level == IPPROTO_IP && optname == IP_OPTIONS) || (level == IPPROTO_IPV6 && optname == IPV6_HOPOPTS); } /** |
5778eabd9 SELinux: extract ... |
481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 |
* selinux_netlbl_socket_setsockopt - Do not allow users to remove a NetLabel * @sock: the socket * @level: the socket level or protocol * @optname: the socket option name * * Description: * Check the setsockopt() call and if the user is trying to replace the IP * options on a socket and a NetLabel is in place for the socket deny the * access; otherwise allow the access. Returns zero when the access is * allowed, -EACCES when denied, and other negative values on error. * */ int selinux_netlbl_socket_setsockopt(struct socket *sock, int level, int optname) { int rc = 0; |
ba6ff9f2b [NetLabel]: conso... |
498 499 |
struct sock *sk = sock->sk; struct sk_security_struct *sksec = sk->sk_security; |
5778eabd9 SELinux: extract ... |
500 |
struct netlbl_lsm_secattr secattr; |
1f440c99d netlabel: Prevent... |
501 |
if (selinux_netlbl_option(level, optname) && |
014ab19a6 selinux: Set sock... |
502 503 |
(sksec->nlbl_state == NLBL_LABELED || sksec->nlbl_state == NLBL_CONNLABELED)) { |
5778eabd9 SELinux: extract ... |
504 |
netlbl_secattr_init(&secattr); |
ba6ff9f2b [NetLabel]: conso... |
505 |
lock_sock(sk); |
050d032b2 selinux: ensure t... |
506 507 508 |
/* call the netlabel function directly as we want to see the * on-the-wire label that is assigned via the socket's options * and not the cached netlabel/lsm attributes */ |
ba6ff9f2b [NetLabel]: conso... |
509 510 |
rc = netlbl_sock_getattr(sk, &secattr); release_sock(sk); |
09c50b4a5 selinux: Fix the ... |
511 |
if (rc == 0) |
5778eabd9 SELinux: extract ... |
512 |
rc = -EACCES; |
09c50b4a5 selinux: Fix the ... |
513 514 |
else if (rc == -ENOMSG) rc = 0; |
5778eabd9 SELinux: extract ... |
515 516 |
netlbl_secattr_destroy(&secattr); } |
5778eabd9 SELinux: extract ... |
517 518 519 |
return rc; } |
014ab19a6 selinux: Set sock... |
520 521 |
/** |
d452930fd selinux: Add SCTP... |
522 523 |
* selinux_netlbl_socket_connect_helper - Help label a client-side socket on * connect |
014ab19a6 selinux: Set sock... |
524 525 526 527 528 529 530 531 |
* @sk: the socket to label * @addr: the destination address * * Description: * Attempt to label a connected socket with NetLabel using the given address. * Returns zero values on success, negative values on failure. * */ |
d452930fd selinux: Add SCTP... |
532 533 |
static int selinux_netlbl_socket_connect_helper(struct sock *sk, struct sockaddr *addr) |
014ab19a6 selinux: Set sock... |
534 535 536 |
{ int rc; struct sk_security_struct *sksec = sk->sk_security; |
6c5b3fc01 selinux: Cache Ne... |
537 |
struct netlbl_lsm_secattr *secattr; |
014ab19a6 selinux: Set sock... |
538 |
|
014ab19a6 selinux: Set sock... |
539 540 541 542 543 544 545 |
/* connected sockets are allowed to disconnect when the address family * is set to AF_UNSPEC, if that is what is happening we want to reset * the socket */ if (addr->sa_family == AF_UNSPEC) { netlbl_sock_delattr(sk); sksec->nlbl_state = NLBL_REQSKB; rc = 0; |
d452930fd selinux: Add SCTP... |
546 |
return rc; |
014ab19a6 selinux: Set sock... |
547 |
} |
6c5b3fc01 selinux: Cache Ne... |
548 549 550 |
secattr = selinux_netlbl_sock_genattr(sk); if (secattr == NULL) { rc = -ENOMEM; |
d452930fd selinux: Add SCTP... |
551 |
return rc; |
6c5b3fc01 selinux: Cache Ne... |
552 553 554 555 |
} rc = netlbl_conn_setattr(sk, addr, secattr); if (rc == 0) sksec->nlbl_state = NLBL_CONNLABELED; |
014ab19a6 selinux: Set sock... |
556 |
|
d452930fd selinux: Add SCTP... |
557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 |
return rc; } /** * selinux_netlbl_socket_connect_locked - Label a client-side socket on * connect * @sk: the socket to label * @addr: the destination address * * Description: * Attempt to label a connected socket that already has the socket locked * with NetLabel using the given address. * Returns zero values on success, negative values on failure. * */ int selinux_netlbl_socket_connect_locked(struct sock *sk, struct sockaddr *addr) { struct sk_security_struct *sksec = sk->sk_security; if (sksec->nlbl_state != NLBL_REQSKB && sksec->nlbl_state != NLBL_CONNLABELED) return 0; return selinux_netlbl_socket_connect_helper(sk, addr); } /** * selinux_netlbl_socket_connect - Label a client-side socket on connect * @sk: the socket to label * @addr: the destination address * * Description: * Attempt to label a connected socket with NetLabel using the given address. * Returns zero values on success, negative values on failure. * */ int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr) { int rc; lock_sock(sk); rc = selinux_netlbl_socket_connect_locked(sk, addr); |
42d64e1ad selinux: correct ... |
600 |
release_sock(sk); |
d452930fd selinux: Add SCTP... |
601 |
|
014ab19a6 selinux: Set sock... |
602 603 |
return rc; } |