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