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