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