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 *sid = SECSID_NULL; 202 return 0; 203 } 204 205 netlbl_secattr_init(&secattr); 206 rc = netlbl_skbuff_getattr(skb, family, &secattr); 207 if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) 208 rc = selinux_netlbl_sidlookup_cached(skb, family, 209 &secattr, sid); 210 else 211 *sid = SECSID_NULL; 212 *type = secattr.type; 213 netlbl_secattr_destroy(&secattr); 214 215 return rc; 216 } 217 218 /** 219 * selinux_netlbl_skbuff_setsid - Set the NetLabel on a packet given a sid 220 * @skb: the packet 221 * @family: protocol family 222 * @sid: the SID 223 * 224 * Description 225 * Call the NetLabel mechanism to set the label of a packet using @sid. 226 * Returns zero on success, negative values on failure. 227 * 228 */ 229 int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, 230 u16 family, 231 u32 sid) 232 { 233 int rc; 234 struct netlbl_lsm_secattr secattr_storage; 235 struct netlbl_lsm_secattr *secattr = NULL; 236 struct sock *sk; 237 238 /* if this is a locally generated packet check to see if it is already 239 * being labeled by it's parent socket, if it is just exit */ 240 sk = skb_to_full_sk(skb); 241 if (sk != NULL) { 242 struct sk_security_struct *sksec = sk->sk_security; 243 244 if (sksec->nlbl_state != NLBL_REQSKB) 245 return 0; 246 secattr = selinux_netlbl_sock_getattr(sk, sid); 247 } 248 if (secattr == NULL) { 249 secattr = &secattr_storage; 250 netlbl_secattr_init(secattr); 251 rc = security_netlbl_sid_to_secattr(sid, secattr); 252 if (rc != 0) 253 goto skbuff_setsid_return; 254 } 255 256 rc = netlbl_skbuff_setattr(skb, family, secattr); 257 258 skbuff_setsid_return: 259 if (secattr == &secattr_storage) 260 netlbl_secattr_destroy(secattr); 261 return rc; 262 } 263 264 /** 265 * selinux_netlbl_sctp_assoc_request - Label an incoming sctp association. 266 * @asoc: incoming association. 267 * @skb: the packet. 268 * 269 * Description: 270 * A new incoming connection is represented by @asoc, ...... 271 * Returns zero on success, negative values on failure. 272 * 273 */ 274 int selinux_netlbl_sctp_assoc_request(struct sctp_association *asoc, 275 struct sk_buff *skb) 276 { 277 int rc; 278 struct netlbl_lsm_secattr secattr; 279 struct sk_security_struct *sksec = asoc->base.sk->sk_security; 280 struct sockaddr_in addr4; 281 struct sockaddr_in6 addr6; 282 283 if (asoc->base.sk->sk_family != PF_INET && 284 asoc->base.sk->sk_family != PF_INET6) 285 return 0; 286 287 netlbl_secattr_init(&secattr); 288 rc = security_netlbl_sid_to_secattr(asoc->secid, &secattr); 289 if (rc != 0) 290 goto assoc_request_return; 291 292 /* Move skb hdr address info to a struct sockaddr and then call 293 * netlbl_conn_setattr(). 294 */ 295 if (ip_hdr(skb)->version == 4) { 296 addr4.sin_family = AF_INET; 297 addr4.sin_addr.s_addr = ip_hdr(skb)->saddr; 298 rc = netlbl_conn_setattr(asoc->base.sk, (void *)&addr4, &secattr); 299 } else if (IS_ENABLED(CONFIG_IPV6) && ip_hdr(skb)->version == 6) { 300 addr6.sin6_family = AF_INET6; 301 addr6.sin6_addr = ipv6_hdr(skb)->saddr; 302 rc = netlbl_conn_setattr(asoc->base.sk, (void *)&addr6, &secattr); 303 } else { 304 rc = -EAFNOSUPPORT; 305 } 306 307 if (rc == 0) 308 sksec->nlbl_state = NLBL_LABELED; 309 310 assoc_request_return: 311 netlbl_secattr_destroy(&secattr); 312 return rc; 313 } 314 315 /** 316 * selinux_netlbl_inet_conn_request - Label an incoming stream connection 317 * @req: incoming connection request socket 318 * @family: the request socket's address family 319 * 320 * Description: 321 * A new incoming connection request is represented by @req, we need to label 322 * the new request_sock here and the stack will ensure the on-the-wire label 323 * will get preserved when a full sock is created once the connection handshake 324 * is complete. Returns zero on success, negative values on failure. 325 * 326 */ 327 int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family) 328 { 329 int rc; 330 struct netlbl_lsm_secattr secattr; 331 332 if (family != PF_INET && family != PF_INET6) 333 return 0; 334 335 netlbl_secattr_init(&secattr); 336 rc = security_netlbl_sid_to_secattr(req->secid, &secattr); 337 if (rc != 0) 338 goto inet_conn_request_return; 339 rc = netlbl_req_setattr(req, &secattr); 340 inet_conn_request_return: 341 netlbl_secattr_destroy(&secattr); 342 return rc; 343 } 344 345 /** 346 * selinux_netlbl_inet_csk_clone - Initialize the newly created sock 347 * @sk: the new sock 348 * @family: the sock's address family 349 * 350 * Description: 351 * A new connection has been established using @sk, we've already labeled the 352 * socket via the request_sock struct in selinux_netlbl_inet_conn_request() but 353 * we need to set the NetLabel state here since we now have a sock structure. 354 * 355 */ 356 void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family) 357 { 358 struct sk_security_struct *sksec = sk->sk_security; 359 360 if (family == PF_INET) 361 sksec->nlbl_state = NLBL_LABELED; 362 else 363 sksec->nlbl_state = NLBL_UNSET; 364 } 365 366 /** 367 * selinux_netlbl_sctp_sk_clone - Copy state to the newly created sock 368 * @sk: current sock 369 * @newsk: the new sock 370 * 371 * Description: 372 * Called whenever a new socket is created by accept(2) or sctp_peeloff(3). 373 */ 374 void selinux_netlbl_sctp_sk_clone(struct sock *sk, struct sock *newsk) 375 { 376 struct sk_security_struct *sksec = sk->sk_security; 377 struct sk_security_struct *newsksec = newsk->sk_security; 378 379 newsksec->nlbl_state = sksec->nlbl_state; 380 } 381 382 /** 383 * selinux_netlbl_socket_post_create - Label a socket using NetLabel 384 * @sk: the sock to label 385 * @family: protocol family 386 * 387 * Description: 388 * Attempt to label a socket using the NetLabel mechanism using the given 389 * SID. Returns zero values on success, negative values on failure. 390 * 391 */ 392 int selinux_netlbl_socket_post_create(struct sock *sk, u16 family) 393 { 394 int rc; 395 struct sk_security_struct *sksec = sk->sk_security; 396 struct netlbl_lsm_secattr *secattr; 397 398 if (family != PF_INET && family != PF_INET6) 399 return 0; 400 401 secattr = selinux_netlbl_sock_genattr(sk); 402 if (secattr == NULL) 403 return -ENOMEM; 404 rc = netlbl_sock_setattr(sk, family, secattr); 405 switch (rc) { 406 case 0: 407 sksec->nlbl_state = NLBL_LABELED; 408 break; 409 case -EDESTADDRREQ: 410 sksec->nlbl_state = NLBL_REQSKB; 411 rc = 0; 412 break; 413 } 414 415 return rc; 416 } 417 418 /** 419 * selinux_netlbl_sock_rcv_skb - Do an inbound access check using NetLabel 420 * @sksec: the sock's sk_security_struct 421 * @skb: the packet 422 * @family: protocol family 423 * @ad: the audit data 424 * 425 * Description: 426 * Fetch the NetLabel security attributes from @skb and perform an access check 427 * against the receiving socket. Returns zero on success, negative values on 428 * error. 429 * 430 */ 431 int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, 432 struct sk_buff *skb, 433 u16 family, 434 struct common_audit_data *ad) 435 { 436 int rc; 437 u32 nlbl_sid; 438 u32 perm; 439 struct netlbl_lsm_secattr secattr; 440 441 if (!netlbl_enabled()) 442 return 0; 443 444 netlbl_secattr_init(&secattr); 445 rc = netlbl_skbuff_getattr(skb, family, &secattr); 446 if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) 447 rc = selinux_netlbl_sidlookup_cached(skb, family, 448 &secattr, &nlbl_sid); 449 else 450 nlbl_sid = SECINITSID_UNLABELED; 451 netlbl_secattr_destroy(&secattr); 452 if (rc != 0) 453 return rc; 454 455 switch (sksec->sclass) { 456 case SECCLASS_UDP_SOCKET: 457 perm = UDP_SOCKET__RECVFROM; 458 break; 459 case SECCLASS_TCP_SOCKET: 460 perm = TCP_SOCKET__RECVFROM; 461 break; 462 default: 463 perm = RAWIP_SOCKET__RECVFROM; 464 } 465 466 rc = avc_has_perm(sksec->sid, nlbl_sid, sksec->sclass, perm, ad); 467 if (rc == 0) 468 return 0; 469 470 if (nlbl_sid != SECINITSID_UNLABELED) 471 netlbl_skbuff_err(skb, family, rc, 0); 472 return rc; 473 } 474 475 /** 476 * selinux_netlbl_option - Is this a NetLabel option 477 * @level: the socket level or protocol 478 * @optname: the socket option name 479 * 480 * Description: 481 * Returns true if @level and @optname refer to a NetLabel option. 482 * Helper for selinux_netlbl_socket_setsockopt(). 483 */ 484 static inline int selinux_netlbl_option(int level, int optname) 485 { 486 return (level == IPPROTO_IP && optname == IP_OPTIONS) || 487 (level == IPPROTO_IPV6 && optname == IPV6_HOPOPTS); 488 } 489 490 /** 491 * selinux_netlbl_socket_setsockopt - Do not allow users to remove a NetLabel 492 * @sock: the socket 493 * @level: the socket level or protocol 494 * @optname: the socket option name 495 * 496 * Description: 497 * Check the setsockopt() call and if the user is trying to replace the IP 498 * options on a socket and a NetLabel is in place for the socket deny the 499 * access; otherwise allow the access. Returns zero when the access is 500 * allowed, -EACCES when denied, and other negative values on error. 501 * 502 */ 503 int selinux_netlbl_socket_setsockopt(struct socket *sock, 504 int level, 505 int optname) 506 { 507 int rc = 0; 508 struct sock *sk = sock->sk; 509 struct sk_security_struct *sksec = sk->sk_security; 510 struct netlbl_lsm_secattr secattr; 511 512 if (selinux_netlbl_option(level, optname) && 513 (sksec->nlbl_state == NLBL_LABELED || 514 sksec->nlbl_state == NLBL_CONNLABELED)) { 515 netlbl_secattr_init(&secattr); 516 lock_sock(sk); 517 /* call the netlabel function directly as we want to see the 518 * on-the-wire label that is assigned via the socket's options 519 * and not the cached netlabel/lsm attributes */ 520 rc = netlbl_sock_getattr(sk, &secattr); 521 release_sock(sk); 522 if (rc == 0) 523 rc = -EACCES; 524 else if (rc == -ENOMSG) 525 rc = 0; 526 netlbl_secattr_destroy(&secattr); 527 } 528 529 return rc; 530 } 531 532 /** 533 * selinux_netlbl_socket_connect_helper - Help label a client-side socket on 534 * connect 535 * @sk: the socket to label 536 * @addr: the destination address 537 * 538 * Description: 539 * Attempt to label a connected socket with NetLabel using the given address. 540 * Returns zero values on success, negative values on failure. 541 * 542 */ 543 static int selinux_netlbl_socket_connect_helper(struct sock *sk, 544 struct sockaddr *addr) 545 { 546 int rc; 547 struct sk_security_struct *sksec = sk->sk_security; 548 struct netlbl_lsm_secattr *secattr; 549 550 /* connected sockets are allowed to disconnect when the address family 551 * is set to AF_UNSPEC, if that is what is happening we want to reset 552 * the socket */ 553 if (addr->sa_family == AF_UNSPEC) { 554 netlbl_sock_delattr(sk); 555 sksec->nlbl_state = NLBL_REQSKB; 556 rc = 0; 557 return rc; 558 } 559 secattr = selinux_netlbl_sock_genattr(sk); 560 if (secattr == NULL) { 561 rc = -ENOMEM; 562 return rc; 563 } 564 rc = netlbl_conn_setattr(sk, addr, secattr); 565 if (rc == 0) 566 sksec->nlbl_state = NLBL_CONNLABELED; 567 568 return rc; 569 } 570 571 /** 572 * selinux_netlbl_socket_connect_locked - Label a client-side socket on 573 * connect 574 * @sk: the socket to label 575 * @addr: the destination address 576 * 577 * Description: 578 * Attempt to label a connected socket that already has the socket locked 579 * with NetLabel using the given address. 580 * Returns zero values on success, negative values on failure. 581 * 582 */ 583 int selinux_netlbl_socket_connect_locked(struct sock *sk, 584 struct sockaddr *addr) 585 { 586 struct sk_security_struct *sksec = sk->sk_security; 587 588 if (sksec->nlbl_state != NLBL_REQSKB && 589 sksec->nlbl_state != NLBL_CONNLABELED) 590 return 0; 591 592 return selinux_netlbl_socket_connect_helper(sk, addr); 593 } 594 595 /** 596 * selinux_netlbl_socket_connect - Label a client-side socket on connect 597 * @sk: the socket to label 598 * @addr: the destination address 599 * 600 * Description: 601 * Attempt to label a connected socket with NetLabel using the given address. 602 * Returns zero values on success, negative values on failure. 603 * 604 */ 605 int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr) 606 { 607 int rc; 608 609 lock_sock(sk); 610 rc = selinux_netlbl_socket_connect_locked(sk, addr); 611 release_sock(sk); 612 613 return rc; 614 } 615