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