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 * @secattr: the NetLabel security attributes 33 * @sid: the SID 34 * 35 * Description: 36 * Query the SELinux security server to lookup the correct SID for the given 37 * security attributes. If the query is successful, cache the result to speed 38 * up future lookups. Returns zero on success, negative values on failure. 39 * 40 */ 41 static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb, 42 u16 family, 43 struct netlbl_lsm_secattr *secattr, 44 u32 *sid) 45 { 46 int rc; 47 48 rc = security_netlbl_secattr_to_sid(&selinux_state, secattr, sid); 49 if (rc == 0 && 50 (secattr->flags & NETLBL_SECATTR_CACHEABLE) && 51 (secattr->flags & NETLBL_SECATTR_CACHE)) 52 netlbl_cache_add(skb, family, secattr); 53 54 return rc; 55 } 56 57 /** 58 * selinux_netlbl_sock_genattr - Generate the NetLabel socket secattr 59 * @sk: the socket 60 * 61 * Description: 62 * Generate the NetLabel security attributes for a socket, making full use of 63 * the socket's attribute cache. Returns a pointer to the security attributes 64 * on success, NULL on failure. 65 * 66 */ 67 static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk) 68 { 69 int rc; 70 struct sk_security_struct *sksec = sk->sk_security; 71 struct netlbl_lsm_secattr *secattr; 72 73 if (sksec->nlbl_secattr != NULL) 74 return sksec->nlbl_secattr; 75 76 secattr = netlbl_secattr_alloc(GFP_ATOMIC); 77 if (secattr == NULL) 78 return NULL; 79 rc = security_netlbl_sid_to_secattr(&selinux_state, sksec->sid, 80 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 * @error: the error code 132 * @gateway: true if host is acting as a gateway, false otherwise 133 * 134 * Description: 135 * When a packet is dropped due to a call to avc_has_perm() pass the error 136 * code to the NetLabel subsystem so any protocol specific processing can be 137 * done. This is safe to call even if you are unsure if NetLabel labeling is 138 * present on the packet, NetLabel is smart enough to only act when it should. 139 * 140 */ 141 void selinux_netlbl_err(struct sk_buff *skb, u16 family, int error, int gateway) 142 { 143 netlbl_skbuff_err(skb, family, error, gateway); 144 } 145 146 /** 147 * selinux_netlbl_sk_security_free - Free the NetLabel fields 148 * @sksec: the sk_security_struct 149 * 150 * Description: 151 * Free all of the memory in the NetLabel fields of a sk_security_struct. 152 * 153 */ 154 void selinux_netlbl_sk_security_free(struct sk_security_struct *sksec) 155 { 156 if (sksec->nlbl_secattr != NULL) 157 netlbl_secattr_free(sksec->nlbl_secattr); 158 } 159 160 /** 161 * selinux_netlbl_sk_security_reset - Reset the NetLabel fields 162 * @sksec: the sk_security_struct 163 * @family: the socket family 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(&selinux_state, sid, 248 secattr); 249 if (rc != 0) 250 goto skbuff_setsid_return; 251 } 252 253 rc = netlbl_skbuff_setattr(skb, family, secattr); 254 255 skbuff_setsid_return: 256 if (secattr == &secattr_storage) 257 netlbl_secattr_destroy(secattr); 258 return rc; 259 } 260 261 /** 262 * selinux_netlbl_sctp_assoc_request - Label an incoming sctp association. 263 * @ep: incoming association endpoint. 264 * @skb: the packet. 265 * 266 * Description: 267 * A new incoming connection is represented by @ep, ...... 268 * Returns zero on success, negative values on failure. 269 * 270 */ 271 int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep, 272 struct sk_buff *skb) 273 { 274 int rc; 275 struct netlbl_lsm_secattr secattr; 276 struct sk_security_struct *sksec = ep->base.sk->sk_security; 277 struct sockaddr_in addr4; 278 struct sockaddr_in6 addr6; 279 280 if (ep->base.sk->sk_family != PF_INET && 281 ep->base.sk->sk_family != PF_INET6) 282 return 0; 283 284 netlbl_secattr_init(&secattr); 285 rc = security_netlbl_sid_to_secattr(&selinux_state, 286 ep->secid, &secattr); 287 if (rc != 0) 288 goto assoc_request_return; 289 290 /* Move skb hdr address info to a struct sockaddr and then call 291 * netlbl_conn_setattr(). 292 */ 293 if (ip_hdr(skb)->version == 4) { 294 addr4.sin_family = AF_INET; 295 addr4.sin_addr.s_addr = ip_hdr(skb)->saddr; 296 rc = netlbl_conn_setattr(ep->base.sk, (void *)&addr4, &secattr); 297 } else if (IS_ENABLED(CONFIG_IPV6) && ip_hdr(skb)->version == 6) { 298 addr6.sin6_family = AF_INET6; 299 addr6.sin6_addr = ipv6_hdr(skb)->saddr; 300 rc = netlbl_conn_setattr(ep->base.sk, (void *)&addr6, &secattr); 301 } else { 302 rc = -EAFNOSUPPORT; 303 } 304 305 if (rc == 0) 306 sksec->nlbl_state = NLBL_LABELED; 307 308 assoc_request_return: 309 netlbl_secattr_destroy(&secattr); 310 return rc; 311 } 312 313 /** 314 * selinux_netlbl_inet_conn_request - Label an incoming stream connection 315 * @req: incoming connection request socket 316 * 317 * Description: 318 * A new incoming connection request is represented by @req, we need to label 319 * the new request_sock here and the stack will ensure the on-the-wire label 320 * will get preserved when a full sock is created once the connection handshake 321 * is complete. Returns zero on success, negative values on failure. 322 * 323 */ 324 int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family) 325 { 326 int rc; 327 struct netlbl_lsm_secattr secattr; 328 329 if (family != PF_INET && family != PF_INET6) 330 return 0; 331 332 netlbl_secattr_init(&secattr); 333 rc = security_netlbl_sid_to_secattr(&selinux_state, req->secid, 334 &secattr); 335 if (rc != 0) 336 goto inet_conn_request_return; 337 rc = netlbl_req_setattr(req, &secattr); 338 inet_conn_request_return: 339 netlbl_secattr_destroy(&secattr); 340 return rc; 341 } 342 343 /** 344 * selinux_netlbl_inet_csk_clone - Initialize the newly created sock 345 * @sk: the new sock 346 * 347 * Description: 348 * A new connection has been established using @sk, we've already labeled the 349 * socket via the request_sock struct in selinux_netlbl_inet_conn_request() but 350 * we need to set the NetLabel state here since we now have a sock structure. 351 * 352 */ 353 void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family) 354 { 355 struct sk_security_struct *sksec = sk->sk_security; 356 357 if (family == PF_INET) 358 sksec->nlbl_state = NLBL_LABELED; 359 else 360 sksec->nlbl_state = NLBL_UNSET; 361 } 362 363 /** 364 * selinux_netlbl_sctp_sk_clone - Copy state to the newly created sock 365 * @sk: current sock 366 * @newsk: the new sock 367 * 368 * Description: 369 * Called whenever a new socket is created by accept(2) or sctp_peeloff(3). 370 */ 371 void selinux_netlbl_sctp_sk_clone(struct sock *sk, struct sock *newsk) 372 { 373 struct sk_security_struct *sksec = sk->sk_security; 374 struct sk_security_struct *newsksec = newsk->sk_security; 375 376 newsksec->nlbl_state = sksec->nlbl_state; 377 } 378 379 /** 380 * selinux_netlbl_socket_post_create - Label a socket using NetLabel 381 * @sock: the socket to label 382 * @family: protocol family 383 * 384 * Description: 385 * Attempt to label a socket using the NetLabel mechanism using the given 386 * SID. Returns zero values on success, negative values on failure. 387 * 388 */ 389 int selinux_netlbl_socket_post_create(struct sock *sk, u16 family) 390 { 391 int rc; 392 struct sk_security_struct *sksec = sk->sk_security; 393 struct netlbl_lsm_secattr *secattr; 394 395 if (family != PF_INET && family != PF_INET6) 396 return 0; 397 398 secattr = selinux_netlbl_sock_genattr(sk); 399 if (secattr == NULL) 400 return -ENOMEM; 401 rc = netlbl_sock_setattr(sk, family, secattr); 402 switch (rc) { 403 case 0: 404 sksec->nlbl_state = NLBL_LABELED; 405 break; 406 case -EDESTADDRREQ: 407 sksec->nlbl_state = NLBL_REQSKB; 408 rc = 0; 409 break; 410 } 411 412 return rc; 413 } 414 415 /** 416 * selinux_netlbl_sock_rcv_skb - Do an inbound access check using NetLabel 417 * @sksec: the sock's sk_security_struct 418 * @skb: the packet 419 * @family: protocol family 420 * @ad: the audit data 421 * 422 * Description: 423 * Fetch the NetLabel security attributes from @skb and perform an access check 424 * against the receiving socket. Returns zero on success, negative values on 425 * error. 426 * 427 */ 428 int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, 429 struct sk_buff *skb, 430 u16 family, 431 struct common_audit_data *ad) 432 { 433 int rc; 434 u32 nlbl_sid; 435 u32 perm; 436 struct netlbl_lsm_secattr secattr; 437 438 if (!netlbl_enabled()) 439 return 0; 440 441 netlbl_secattr_init(&secattr); 442 rc = netlbl_skbuff_getattr(skb, family, &secattr); 443 if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) 444 rc = selinux_netlbl_sidlookup_cached(skb, family, 445 &secattr, &nlbl_sid); 446 else 447 nlbl_sid = SECINITSID_UNLABELED; 448 netlbl_secattr_destroy(&secattr); 449 if (rc != 0) 450 return rc; 451 452 switch (sksec->sclass) { 453 case SECCLASS_UDP_SOCKET: 454 perm = UDP_SOCKET__RECVFROM; 455 break; 456 case SECCLASS_TCP_SOCKET: 457 perm = TCP_SOCKET__RECVFROM; 458 break; 459 default: 460 perm = RAWIP_SOCKET__RECVFROM; 461 } 462 463 rc = avc_has_perm(&selinux_state, 464 sksec->sid, nlbl_sid, sksec->sclass, perm, ad); 465 if (rc == 0) 466 return 0; 467 468 if (nlbl_sid != SECINITSID_UNLABELED) 469 netlbl_skbuff_err(skb, family, rc, 0); 470 return rc; 471 } 472 473 /** 474 * selinux_netlbl_option - Is this a NetLabel option 475 * @level: the socket level or protocol 476 * @optname: the socket option name 477 * 478 * Description: 479 * Returns true if @level and @optname refer to a NetLabel option. 480 * Helper for selinux_netlbl_socket_setsockopt(). 481 */ 482 static inline int selinux_netlbl_option(int level, int optname) 483 { 484 return (level == IPPROTO_IP && optname == IP_OPTIONS) || 485 (level == IPPROTO_IPV6 && optname == IPV6_HOPOPTS); 486 } 487 488 /** 489 * selinux_netlbl_socket_setsockopt - Do not allow users to remove a NetLabel 490 * @sock: the socket 491 * @level: the socket level or protocol 492 * @optname: the socket option name 493 * 494 * Description: 495 * Check the setsockopt() call and if the user is trying to replace the IP 496 * options on a socket and a NetLabel is in place for the socket deny the 497 * access; otherwise allow the access. Returns zero when the access is 498 * allowed, -EACCES when denied, and other negative values on error. 499 * 500 */ 501 int selinux_netlbl_socket_setsockopt(struct socket *sock, 502 int level, 503 int optname) 504 { 505 int rc = 0; 506 struct sock *sk = sock->sk; 507 struct sk_security_struct *sksec = sk->sk_security; 508 struct netlbl_lsm_secattr secattr; 509 510 if (selinux_netlbl_option(level, optname) && 511 (sksec->nlbl_state == NLBL_LABELED || 512 sksec->nlbl_state == NLBL_CONNLABELED)) { 513 netlbl_secattr_init(&secattr); 514 lock_sock(sk); 515 /* call the netlabel function directly as we want to see the 516 * on-the-wire label that is assigned via the socket's options 517 * and not the cached netlabel/lsm attributes */ 518 rc = netlbl_sock_getattr(sk, &secattr); 519 release_sock(sk); 520 if (rc == 0) 521 rc = -EACCES; 522 else if (rc == -ENOMSG) 523 rc = 0; 524 netlbl_secattr_destroy(&secattr); 525 } 526 527 return rc; 528 } 529 530 /** 531 * selinux_netlbl_socket_connect_helper - Help label a client-side socket on 532 * connect 533 * @sk: the socket to label 534 * @addr: the destination address 535 * 536 * Description: 537 * Attempt to label a connected socket with NetLabel using the given address. 538 * Returns zero values on success, negative values on failure. 539 * 540 */ 541 static int selinux_netlbl_socket_connect_helper(struct sock *sk, 542 struct sockaddr *addr) 543 { 544 int rc; 545 struct sk_security_struct *sksec = sk->sk_security; 546 struct netlbl_lsm_secattr *secattr; 547 548 /* connected sockets are allowed to disconnect when the address family 549 * is set to AF_UNSPEC, if that is what is happening we want to reset 550 * the socket */ 551 if (addr->sa_family == AF_UNSPEC) { 552 netlbl_sock_delattr(sk); 553 sksec->nlbl_state = NLBL_REQSKB; 554 rc = 0; 555 return rc; 556 } 557 secattr = selinux_netlbl_sock_genattr(sk); 558 if (secattr == NULL) { 559 rc = -ENOMEM; 560 return rc; 561 } 562 rc = netlbl_conn_setattr(sk, addr, secattr); 563 if (rc == 0) 564 sksec->nlbl_state = NLBL_CONNLABELED; 565 566 return rc; 567 } 568 569 /** 570 * selinux_netlbl_socket_connect_locked - Label a client-side socket on 571 * connect 572 * @sk: the socket to label 573 * @addr: the destination address 574 * 575 * Description: 576 * Attempt to label a connected socket that already has the socket locked 577 * with NetLabel using the given address. 578 * Returns zero values on success, negative values on failure. 579 * 580 */ 581 int selinux_netlbl_socket_connect_locked(struct sock *sk, 582 struct sockaddr *addr) 583 { 584 struct sk_security_struct *sksec = sk->sk_security; 585 586 if (sksec->nlbl_state != NLBL_REQSKB && 587 sksec->nlbl_state != NLBL_CONNLABELED) 588 return 0; 589 590 return selinux_netlbl_socket_connect_helper(sk, addr); 591 } 592 593 /** 594 * selinux_netlbl_socket_connect - Label a client-side socket on connect 595 * @sk: the socket to label 596 * @addr: the destination address 597 * 598 * Description: 599 * Attempt to label a connected socket with NetLabel using the given address. 600 * Returns zero values on success, negative values on failure. 601 * 602 */ 603 int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr) 604 { 605 int rc; 606 607 lock_sock(sk); 608 rc = selinux_netlbl_socket_connect_locked(sk, addr); 609 release_sock(sk); 610 611 return rc; 612 } 613