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 rc = netlbl_sock_setattr(sk, family, secattr); 406 switch (rc) { 407 case 0: 408 sksec->nlbl_state = NLBL_LABELED; 409 break; 410 case -EDESTADDRREQ: 411 sksec->nlbl_state = NLBL_REQSKB; 412 rc = 0; 413 break; 414 } 415 416 return rc; 417 } 418 419 /** 420 * selinux_netlbl_sock_rcv_skb - Do an inbound access check using NetLabel 421 * @sksec: the sock's sk_security_struct 422 * @skb: the packet 423 * @family: protocol family 424 * @ad: the audit data 425 * 426 * Description: 427 * Fetch the NetLabel security attributes from @skb and perform an access check 428 * against the receiving socket. Returns zero on success, negative values on 429 * error. 430 * 431 */ 432 int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, 433 struct sk_buff *skb, 434 u16 family, 435 struct common_audit_data *ad) 436 { 437 int rc; 438 u32 nlbl_sid; 439 u32 perm; 440 struct netlbl_lsm_secattr secattr; 441 442 if (!netlbl_enabled()) 443 return 0; 444 445 netlbl_secattr_init(&secattr); 446 rc = netlbl_skbuff_getattr(skb, family, &secattr); 447 if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) 448 rc = selinux_netlbl_sidlookup_cached(skb, family, 449 &secattr, &nlbl_sid); 450 else 451 nlbl_sid = SECINITSID_UNLABELED; 452 netlbl_secattr_destroy(&secattr); 453 if (rc != 0) 454 return rc; 455 456 switch (sksec->sclass) { 457 case SECCLASS_UDP_SOCKET: 458 perm = UDP_SOCKET__RECVFROM; 459 break; 460 case SECCLASS_TCP_SOCKET: 461 perm = TCP_SOCKET__RECVFROM; 462 break; 463 default: 464 perm = RAWIP_SOCKET__RECVFROM; 465 } 466 467 rc = avc_has_perm(sksec->sid, nlbl_sid, sksec->sclass, perm, ad); 468 if (rc == 0) 469 return 0; 470 471 if (nlbl_sid != SECINITSID_UNLABELED) 472 netlbl_skbuff_err(skb, family, rc, 0); 473 return rc; 474 } 475 476 /** 477 * selinux_netlbl_option - Is this a NetLabel option 478 * @level: the socket level or protocol 479 * @optname: the socket option name 480 * 481 * Description: 482 * Returns true if @level and @optname refer to a NetLabel option. 483 * Helper for selinux_netlbl_socket_setsockopt(). 484 */ 485 static inline int selinux_netlbl_option(int level, int optname) 486 { 487 return (level == IPPROTO_IP && optname == IP_OPTIONS) || 488 (level == IPPROTO_IPV6 && optname == IPV6_HOPOPTS); 489 } 490 491 /** 492 * selinux_netlbl_socket_setsockopt - Do not allow users to remove a NetLabel 493 * @sock: the socket 494 * @level: the socket level or protocol 495 * @optname: the socket option name 496 * 497 * Description: 498 * Check the setsockopt() call and if the user is trying to replace the IP 499 * options on a socket and a NetLabel is in place for the socket deny the 500 * access; otherwise allow the access. Returns zero when the access is 501 * allowed, -EACCES when denied, and other negative values on error. 502 * 503 */ 504 int selinux_netlbl_socket_setsockopt(struct socket *sock, 505 int level, 506 int optname) 507 { 508 int rc = 0; 509 struct sock *sk = sock->sk; 510 struct sk_security_struct *sksec = sk->sk_security; 511 struct netlbl_lsm_secattr secattr; 512 513 if (selinux_netlbl_option(level, optname) && 514 (sksec->nlbl_state == NLBL_LABELED || 515 sksec->nlbl_state == NLBL_CONNLABELED)) { 516 netlbl_secattr_init(&secattr); 517 lock_sock(sk); 518 /* call the netlabel function directly as we want to see the 519 * on-the-wire label that is assigned via the socket's options 520 * and not the cached netlabel/lsm attributes */ 521 rc = netlbl_sock_getattr(sk, &secattr); 522 release_sock(sk); 523 if (rc == 0) 524 rc = -EACCES; 525 else if (rc == -ENOMSG) 526 rc = 0; 527 netlbl_secattr_destroy(&secattr); 528 } 529 530 return rc; 531 } 532 533 /** 534 * selinux_netlbl_socket_connect_helper - Help label a client-side socket on 535 * connect 536 * @sk: the socket to label 537 * @addr: the destination address 538 * 539 * Description: 540 * Attempt to label a connected socket with NetLabel using the given address. 541 * Returns zero values on success, negative values on failure. 542 * 543 */ 544 static int selinux_netlbl_socket_connect_helper(struct sock *sk, 545 struct sockaddr *addr) 546 { 547 int rc; 548 struct sk_security_struct *sksec = sk->sk_security; 549 struct netlbl_lsm_secattr *secattr; 550 551 /* connected sockets are allowed to disconnect when the address family 552 * is set to AF_UNSPEC, if that is what is happening we want to reset 553 * the socket */ 554 if (addr->sa_family == AF_UNSPEC) { 555 netlbl_sock_delattr(sk); 556 sksec->nlbl_state = NLBL_REQSKB; 557 rc = 0; 558 return rc; 559 } 560 secattr = selinux_netlbl_sock_genattr(sk); 561 if (secattr == NULL) { 562 rc = -ENOMEM; 563 return rc; 564 } 565 rc = netlbl_conn_setattr(sk, addr, secattr); 566 if (rc == 0) 567 sksec->nlbl_state = NLBL_CONNLABELED; 568 569 return rc; 570 } 571 572 /** 573 * selinux_netlbl_socket_connect_locked - Label a client-side socket on 574 * connect 575 * @sk: the socket to label 576 * @addr: the destination address 577 * 578 * Description: 579 * Attempt to label a connected socket that already has the socket locked 580 * with NetLabel using the given address. 581 * Returns zero values on success, negative values on failure. 582 * 583 */ 584 int selinux_netlbl_socket_connect_locked(struct sock *sk, 585 struct sockaddr *addr) 586 { 587 struct sk_security_struct *sksec = sk->sk_security; 588 589 if (sksec->nlbl_state != NLBL_REQSKB && 590 sksec->nlbl_state != NLBL_CONNLABELED) 591 return 0; 592 593 return selinux_netlbl_socket_connect_helper(sk, addr); 594 } 595 596 /** 597 * selinux_netlbl_socket_connect - Label a client-side socket on connect 598 * @sk: the socket to label 599 * @addr: the destination address 600 * 601 * Description: 602 * Attempt to label a connected socket with NetLabel using the given address. 603 * Returns zero values on success, negative values on failure. 604 * 605 */ 606 int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr) 607 { 608 int rc; 609 610 lock_sock(sk); 611 rc = selinux_netlbl_socket_connect_locked(sk, addr); 612 release_sock(sk); 613 614 return rc; 615 } 616