1/* 2 * Copyright (c) 2003-2007 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29#include <sys/kpi_socketfilter.h> 30 31#include <sys/socket.h> 32#include <sys/param.h> 33#include <sys/errno.h> 34#include <sys/malloc.h> 35#include <sys/protosw.h> 36#include <sys/domain.h> 37#include <sys/proc.h> 38#include <kern/locks.h> 39#include <kern/thread.h> 40#include <kern/debug.h> 41#include <net/kext_net.h> 42#include <net/if.h> 43#include <netinet/in_var.h> 44#include <netinet/ip.h> 45#include <netinet/ip_var.h> 46#include <netinet/tcp.h> 47#include <netinet/tcp_var.h> 48#include <netinet/udp.h> 49#include <netinet/udp_var.h> 50 51#include <libkern/libkern.h> 52#include <libkern/OSAtomic.h> 53 54#include <string.h> 55 56#define SFEF_ATTACHED 0x1 /* SFE is on socket list */ 57#define SFEF_NODETACH 0x2 /* Detach should not be called */ 58#define SFEF_NOSOCKET 0x4 /* Socket is gone */ 59 60struct socket_filter_entry { 61 struct socket_filter_entry *sfe_next_onsocket; 62 struct socket_filter_entry *sfe_next_onfilter; 63 struct socket_filter_entry *sfe_next_oncleanup; 64 65 struct socket_filter *sfe_filter; 66 struct socket *sfe_socket; 67 void *sfe_cookie; 68 69 uint32_t sfe_flags; 70 int32_t sfe_refcount; 71}; 72 73struct socket_filter { 74 TAILQ_ENTRY(socket_filter) sf_protosw_next; 75 TAILQ_ENTRY(socket_filter) sf_global_next; 76 struct socket_filter_entry *sf_entry_head; 77 78 struct protosw *sf_proto; 79 struct sflt_filter sf_filter; 80 u_int32_t sf_refcount; 81}; 82 83TAILQ_HEAD(socket_filter_list, socket_filter); 84 85static struct socket_filter_list sock_filter_head; 86static lck_rw_t *sock_filter_lock = NULL; 87static lck_mtx_t *sock_filter_cleanup_lock = NULL; 88static struct socket_filter_entry *sock_filter_cleanup_entries = NULL; 89static thread_t sock_filter_cleanup_thread = NULL; 90 91static void sflt_cleanup_thread(void *, wait_result_t); 92static void sflt_detach_locked(struct socket_filter_entry *entry); 93 94#pragma mark -- Internal State Management -- 95 96__private_extern__ void 97sflt_init(void) 98{ 99 lck_grp_attr_t *grp_attrib = 0; 100 lck_attr_t *lck_attrib = 0; 101 lck_grp_t *lck_group = 0; 102 103 TAILQ_INIT(&sock_filter_head); 104 105 /* Allocate a rw lock */ 106 grp_attrib = lck_grp_attr_alloc_init(); 107 lck_group = lck_grp_alloc_init("socket filter lock", grp_attrib); 108 lck_grp_attr_free(grp_attrib); 109 lck_attrib = lck_attr_alloc_init(); 110 sock_filter_lock = lck_rw_alloc_init(lck_group, lck_attrib); 111 sock_filter_cleanup_lock = lck_mtx_alloc_init(lck_group, lck_attrib); 112 lck_grp_free(lck_group); 113 lck_attr_free(lck_attrib); 114} 115 116static void 117sflt_retain_locked( 118 struct socket_filter *filter) 119{ 120 filter->sf_refcount++; 121} 122 123static void 124sflt_release_locked( 125 struct socket_filter *filter) 126{ 127 filter->sf_refcount--; 128 if (filter->sf_refcount == 0) 129 { 130 // Call the unregistered function 131 if (filter->sf_filter.sf_unregistered) { 132 lck_rw_unlock_exclusive(sock_filter_lock); 133 filter->sf_filter.sf_unregistered(filter->sf_filter.sf_handle); 134 lck_rw_lock_exclusive(sock_filter_lock); 135 } 136 137 // Free the entry 138 FREE(filter, M_IFADDR); 139 } 140} 141 142static void 143sflt_entry_retain( 144 struct socket_filter_entry *entry) 145{ 146 if (OSIncrementAtomic(&entry->sfe_refcount) <= 0) 147 panic("sflt_entry_retain - sfe_refcount <= 0\n"); 148} 149 150static void 151sflt_entry_release( 152 struct socket_filter_entry *entry) 153{ 154 SInt32 old = OSDecrementAtomic(&entry->sfe_refcount); 155 if (old == 1) { 156 // That was the last reference 157 158 // Take the cleanup lock 159 lck_mtx_lock(sock_filter_cleanup_lock); 160 161 // Put this item on the cleanup list 162 entry->sfe_next_oncleanup = sock_filter_cleanup_entries; 163 sock_filter_cleanup_entries = entry; 164 165 // If the item is the first item in the list 166 if (entry->sfe_next_oncleanup == NULL) { 167 if (sock_filter_cleanup_thread == NULL) { 168 // Create a thread 169 kernel_thread_start(sflt_cleanup_thread, NULL, &sock_filter_cleanup_thread); 170 } else { 171 // Wakeup the thread 172 wakeup(&sock_filter_cleanup_entries); 173 } 174 } 175 176 // Drop the cleanup lock 177 lck_mtx_unlock(sock_filter_cleanup_lock); 178 } 179 else if (old <= 0) 180 { 181 panic("sflt_entry_release - sfe_refcount (%d) <= 0\n", (int)old); 182 } 183} 184 185static void 186sflt_cleanup_thread( 187 __unused void * blah, 188 __unused wait_result_t blah2) 189{ 190 while (1) { 191 lck_mtx_lock(sock_filter_cleanup_lock); 192 while (sock_filter_cleanup_entries == NULL) { 193 // Sleep until we've got something better to do 194 msleep(&sock_filter_cleanup_entries, sock_filter_cleanup_lock, PWAIT, "sflt_cleanup", NULL); 195 } 196 197 // Pull the current list of dead items 198 struct socket_filter_entry *dead = sock_filter_cleanup_entries; 199 sock_filter_cleanup_entries = NULL; 200 201 // Drop the lock 202 lck_mtx_unlock(sock_filter_cleanup_lock); 203 204 // Take the socket filter lock 205 lck_rw_lock_exclusive(sock_filter_lock); 206 207 // Cleanup every dead item 208 struct socket_filter_entry *entry; 209 for (entry = dead; entry; entry = dead) { 210 struct socket_filter_entry **nextpp; 211 212 dead = entry->sfe_next_oncleanup; 213 214 // Call the detach function if necessary - drop the lock 215 if ((entry->sfe_flags & SFEF_NODETACH) == 0 && 216 entry->sfe_filter->sf_filter.sf_detach) { 217 entry->sfe_flags |= SFEF_NODETACH; 218 lck_rw_unlock_exclusive(sock_filter_lock); 219 220 // Warning - passing a potentially dead socket may be bad 221 entry->sfe_filter->sf_filter. 222 sf_detach(entry->sfe_cookie, entry->sfe_socket); 223 224 lck_rw_lock_exclusive(sock_filter_lock); 225 } 226 227 // Pull entry off the socket list -- if the socket still exists 228 if ((entry->sfe_flags & SFEF_NOSOCKET) == 0) { 229 for (nextpp = &entry->sfe_socket->so_filt; *nextpp; 230 nextpp = &(*nextpp)->sfe_next_onsocket) { 231 if (*nextpp == entry) { 232 *nextpp = entry->sfe_next_onsocket; 233 break; 234 } 235 } 236 } 237 238 // Pull entry off the filter list 239 for (nextpp = &entry->sfe_filter->sf_entry_head; *nextpp; 240 nextpp = &(*nextpp)->sfe_next_onfilter) { 241 if (*nextpp == entry) { 242 *nextpp = entry->sfe_next_onfilter; 243 break; 244 } 245 } 246 247 // Release the filter -- may drop lock, but that's okay 248 sflt_release_locked(entry->sfe_filter); 249 entry->sfe_socket = NULL; 250 entry->sfe_filter = NULL; 251 FREE(entry, M_IFADDR); 252 } 253 254 // Drop the socket filter lock 255 lck_rw_unlock_exclusive(sock_filter_lock); 256 } 257 // Not reached 258} 259 260static int 261sflt_attach_locked( 262 struct socket *so, 263 struct socket_filter *filter, 264 int socklocked) 265{ 266 int error = 0; 267 struct socket_filter_entry *entry = NULL; 268 269 if (filter == NULL) 270 return ENOENT; 271 272 for (entry = so->so_filt; entry; entry = entry->sfe_next_onfilter) 273 if (entry->sfe_filter->sf_filter.sf_handle == 274 filter->sf_filter.sf_handle) 275 return EEXIST; 276 277 /* allocate the socket filter entry */ 278 MALLOC(entry, struct socket_filter_entry *, sizeof(*entry), M_IFADDR, 279 M_WAITOK); 280 if (entry == NULL) 281 return ENOMEM; 282 283 /* Initialize the socket filter entry */ 284 entry->sfe_cookie = NULL; 285 entry->sfe_flags = SFEF_ATTACHED; 286 entry->sfe_refcount = 1; // corresponds to SFEF_ATTACHED flag set 287 288 /* Put the entry in the filter list */ 289 sflt_retain_locked(filter); 290 entry->sfe_filter = filter; 291 entry->sfe_next_onfilter = filter->sf_entry_head; 292 filter->sf_entry_head = entry; 293 294 /* Put the entry on the socket filter list */ 295 entry->sfe_socket = so; 296 entry->sfe_next_onsocket = so->so_filt; 297 so->so_filt = entry; 298 299 if (entry->sfe_filter->sf_filter.sf_attach) { 300 // Retain the entry while we call attach 301 sflt_entry_retain(entry); 302 303 // Release the filter lock -- callers must be aware we will do this 304 lck_rw_unlock_exclusive(sock_filter_lock); 305 306 // Unlock the socket 307 if (socklocked) 308 socket_unlock(so, 0); 309 310 // It's finally safe to call the filter function 311 error = entry->sfe_filter->sf_filter.sf_attach(&entry->sfe_cookie, so); 312 313 // Lock the socket again 314 if (socklocked) 315 socket_lock(so, 0); 316 317 // Lock the filters again 318 lck_rw_lock_exclusive(sock_filter_lock); 319 320 // If the attach function returns an error, this filter must be detached 321 if (error) { 322 entry->sfe_flags |= SFEF_NODETACH; // don't call sf_detach 323 sflt_detach_locked(entry); 324 } 325 326 // Release the retain we held through the attach call 327 sflt_entry_release(entry); 328 } 329 330 return error; 331} 332 333errno_t 334sflt_attach_internal( 335 socket_t socket, 336 sflt_handle handle) 337{ 338 if (socket == NULL || handle == 0) 339 return EINVAL; 340 341 int result = EINVAL; 342 343 lck_rw_lock_exclusive(sock_filter_lock); 344 345 struct socket_filter *filter = NULL; 346 TAILQ_FOREACH(filter, &sock_filter_head, sf_global_next) { 347 if (filter->sf_filter.sf_handle == handle) break; 348 } 349 350 if (filter) { 351 result = sflt_attach_locked(socket, filter, 1); 352 } 353 354 lck_rw_unlock_exclusive(sock_filter_lock); 355 356 return result; 357} 358 359static void 360sflt_detach_locked( 361 struct socket_filter_entry *entry) 362{ 363 if ((entry->sfe_flags & SFEF_ATTACHED) != 0) { 364 entry->sfe_flags &= ~SFEF_ATTACHED; 365 sflt_entry_release(entry); 366 } 367} 368 369#pragma mark -- Socket Layer Hooks -- 370 371__private_extern__ void 372sflt_initsock( 373 struct socket *so) 374{ 375 struct protosw *proto = so->so_proto; 376 377 lck_rw_lock_shared(sock_filter_lock); 378 if (TAILQ_FIRST(&proto->pr_filter_head) != NULL) { 379 // Promote lock to exclusive 380 if (!lck_rw_lock_shared_to_exclusive(sock_filter_lock)) 381 lck_rw_lock_exclusive(sock_filter_lock); 382 383 // Warning: A filter unregistering will be pulled out of the list. 384 // This could happen while we drop the lock in sftl_attach_locked 385 // or sflt_release_locked. For this reason we retain a reference 386 // on the filter (or next_filter) while calling this function 387 // 388 // This protects us from a panic, but it could result in a 389 // socket being created without all of the global filters if 390 // we're attaching a filter as it is removed, if that's possible. 391 struct socket_filter *filter = TAILQ_FIRST(&proto->pr_filter_head); 392 sflt_retain_locked(filter); 393 394 while (filter) 395 { 396 struct socket_filter *filter_next; 397 398 // Warning: sflt_attach_private_locked will drop the lock 399 sflt_attach_locked(so, filter, 0); 400 401 filter_next = TAILQ_NEXT(filter, sf_protosw_next); 402 if (filter_next) 403 sflt_retain_locked(filter_next); 404 405 // Warning: filt_release_locked may remove the filter from the queue 406 sflt_release_locked(filter); 407 filter = filter_next; 408 } 409 } 410 lck_rw_done(sock_filter_lock); 411} 412 413/* 414 * sflt_termsock 415 * 416 * Detaches all filters from the socket. 417 */ 418 419__private_extern__ void 420sflt_termsock( 421 struct socket *so) 422{ 423 lck_rw_lock_exclusive(sock_filter_lock); 424 425 struct socket_filter_entry *entry; 426 427 while ((entry = so->so_filt) != NULL) { 428 // Pull filter off the socket 429 so->so_filt = entry->sfe_next_onsocket; 430 entry->sfe_flags |= SFEF_NOSOCKET; 431 432 // Call detach 433 sflt_detach_locked(entry); 434 435 // On sflt_termsock, we can't return until the detach function has been called 436 // Call the detach function - this is gross because the socket filter 437 // entry could be freed when we drop the lock, so we make copies on 438 // the stack and retain everything we need before dropping the lock 439 if ((entry->sfe_flags & SFEF_NODETACH) == 0 && 440 entry->sfe_filter->sf_filter.sf_detach) { 441 void *sfe_cookie = entry->sfe_cookie; 442 struct socket_filter *sfe_filter = entry->sfe_filter; 443 444 // Retain the socket filter 445 sflt_retain_locked(sfe_filter); 446 447 // Mark that we've called the detach function 448 entry->sfe_flags |= SFEF_NODETACH; 449 450 // Drop the lock around the call to the detach function 451 lck_rw_unlock_exclusive(sock_filter_lock); 452 sfe_filter->sf_filter.sf_detach(sfe_cookie, so); 453 lck_rw_lock_exclusive(sock_filter_lock); 454 455 // Release the filter 456 sflt_release_locked(sfe_filter); 457 } 458 } 459 460 lck_rw_unlock_exclusive(sock_filter_lock); 461} 462 463 464static void 465sflt_notify_internal( 466 struct socket *so, 467 sflt_event_t event, 468 void *param, 469 sflt_handle handle) 470{ 471 if (so->so_filt == NULL) return; 472 473 struct socket_filter_entry *entry; 474 int unlocked = 0; 475 476 lck_rw_lock_shared(sock_filter_lock); 477 for (entry = so->so_filt; entry; entry = entry->sfe_next_onsocket) { 478 if ((entry->sfe_flags & SFEF_ATTACHED) 479 && entry->sfe_filter->sf_filter.sf_notify && 480 ((handle && entry->sfe_filter->sf_filter.sf_handle != handle) || 481 !handle)) { 482 // Retain the filter entry and release the socket filter lock 483 sflt_entry_retain(entry); 484 lck_rw_unlock_shared(sock_filter_lock); 485 486 // If the socket isn't already unlocked, unlock it 487 if (unlocked == 0) { 488 unlocked = 1; 489 socket_unlock(so, 0); 490 } 491 492 // Finally call the filter 493 entry->sfe_filter->sf_filter. 494 sf_notify(entry->sfe_cookie, so, event, param); 495 496 // Take the socket filter lock again and release the entry 497 lck_rw_lock_shared(sock_filter_lock); 498 sflt_entry_release(entry); 499 } 500 } 501 lck_rw_unlock_shared(sock_filter_lock); 502 503 if (unlocked != 0) { 504 socket_lock(so, 0); 505 } 506} 507 508__private_extern__ void 509sflt_notify( 510 struct socket *so, 511 sflt_event_t event, 512 void *param) 513{ 514 sflt_notify_internal(so, event, param, 0); 515} 516 517static void 518sflt_notify_after_register( 519 struct socket *so, 520 sflt_event_t event, 521 sflt_handle handle) 522{ 523 sflt_notify_internal(so, event, NULL, handle); 524} 525 526__private_extern__ int 527sflt_ioctl( 528 struct socket *so, 529 u_long cmd, 530 caddr_t data) 531{ 532 if (so->so_filt == NULL) return 0; 533 534 struct socket_filter_entry *entry; 535 int unlocked = 0; 536 int error = 0; 537 538 lck_rw_lock_shared(sock_filter_lock); 539 for (entry = so->so_filt; entry && error == 0; 540 entry = entry->sfe_next_onsocket) { 541 if ((entry->sfe_flags & SFEF_ATTACHED) 542 && entry->sfe_filter->sf_filter.sf_ioctl) { 543 // Retain the filter entry and release the socket filter lock 544 sflt_entry_retain(entry); 545 lck_rw_unlock_shared(sock_filter_lock); 546 547 // If the socket isn't already unlocked, unlock it 548 if (unlocked == 0) { 549 socket_unlock(so, 0); 550 unlocked = 1; 551 } 552 553 // Call the filter 554 error = entry->sfe_filter->sf_filter. 555 sf_ioctl(entry->sfe_cookie, so, cmd, data); 556 557 // Take the socket filter lock again and release the entry 558 lck_rw_lock_shared(sock_filter_lock); 559 sflt_entry_release(entry); 560 } 561 } 562 lck_rw_unlock_shared(sock_filter_lock); 563 564 if (unlocked) { 565 socket_lock(so, 0); 566 } 567 568 return error; 569} 570 571__private_extern__ int 572sflt_bind( 573 struct socket *so, 574 const struct sockaddr *nam) 575{ 576 if (so->so_filt == NULL) return 0; 577 578 struct socket_filter_entry *entry; 579 int unlocked = 0; 580 int error = 0; 581 582 lck_rw_lock_shared(sock_filter_lock); 583 for (entry = so->so_filt; entry && error == 0; 584 entry = entry->sfe_next_onsocket) { 585 if ((entry->sfe_flags & SFEF_ATTACHED) 586 && entry->sfe_filter->sf_filter.sf_bind) { 587 // Retain the filter entry and release the socket filter lock 588 sflt_entry_retain(entry); 589 lck_rw_unlock_shared(sock_filter_lock); 590 591 // If the socket isn't already unlocked, unlock it 592 if (unlocked == 0) { 593 socket_unlock(so, 0); 594 unlocked = 1; 595 } 596 597 // Call the filter 598 error = entry->sfe_filter->sf_filter. 599 sf_bind(entry->sfe_cookie, so, nam); 600 601 // Take the socket filter lock again and release the entry 602 lck_rw_lock_shared(sock_filter_lock); 603 sflt_entry_release(entry); 604 } 605 } 606 lck_rw_unlock_shared(sock_filter_lock); 607 608 if (unlocked) { 609 socket_lock(so, 0); 610 } 611 612 return error; 613} 614 615__private_extern__ int 616sflt_listen( 617 struct socket *so) 618{ 619 if (so->so_filt == NULL) return 0; 620 621 struct socket_filter_entry *entry; 622 int unlocked = 0; 623 int error = 0; 624 625 lck_rw_lock_shared(sock_filter_lock); 626 for (entry = so->so_filt; entry && error == 0; 627 entry = entry->sfe_next_onsocket) { 628 if ((entry->sfe_flags & SFEF_ATTACHED) 629 && entry->sfe_filter->sf_filter.sf_listen) { 630 // Retain the filter entry and release the socket filter lock 631 sflt_entry_retain(entry); 632 lck_rw_unlock_shared(sock_filter_lock); 633 634 // If the socket isn't already unlocked, unlock it 635 if (unlocked == 0) { 636 socket_unlock(so, 0); 637 unlocked = 1; 638 } 639 640 // Call the filter 641 error = entry->sfe_filter->sf_filter. 642 sf_listen(entry->sfe_cookie, so); 643 644 // Take the socket filter lock again and release the entry 645 lck_rw_lock_shared(sock_filter_lock); 646 sflt_entry_release(entry); 647 } 648 } 649 lck_rw_unlock_shared(sock_filter_lock); 650 651 if (unlocked) { 652 socket_lock(so, 0); 653 } 654 655 return error; 656} 657 658__private_extern__ int 659sflt_accept( 660 struct socket *head, 661 struct socket *so, 662 const struct sockaddr *local, 663 const struct sockaddr *remote) 664{ 665 if (so->so_filt == NULL) return 0; 666 667 struct socket_filter_entry *entry; 668 int unlocked = 0; 669 int error = 0; 670 671 lck_rw_lock_shared(sock_filter_lock); 672 for (entry = so->so_filt; entry && error == 0; 673 entry = entry->sfe_next_onsocket) { 674 if ((entry->sfe_flags & SFEF_ATTACHED) 675 && entry->sfe_filter->sf_filter.sf_accept) { 676 // Retain the filter entry and release the socket filter lock 677 sflt_entry_retain(entry); 678 lck_rw_unlock_shared(sock_filter_lock); 679 680 // If the socket isn't already unlocked, unlock it 681 if (unlocked == 0) { 682 socket_unlock(so, 0); 683 unlocked = 1; 684 } 685 686 // Call the filter 687 error = entry->sfe_filter->sf_filter. 688 sf_accept(entry->sfe_cookie, head, so, local, remote); 689 690 // Take the socket filter lock again and release the entry 691 lck_rw_lock_shared(sock_filter_lock); 692 sflt_entry_release(entry); 693 } 694 } 695 lck_rw_unlock_shared(sock_filter_lock); 696 697 if (unlocked) { 698 socket_lock(so, 0); 699 } 700 701 return error; 702} 703 704__private_extern__ int 705sflt_getsockname( 706 struct socket *so, 707 struct sockaddr **local) 708{ 709 if (so->so_filt == NULL) return 0; 710 711 struct socket_filter_entry *entry; 712 int unlocked = 0; 713 int error = 0; 714 715 lck_rw_lock_shared(sock_filter_lock); 716 for (entry = so->so_filt; entry && error == 0; 717 entry = entry->sfe_next_onsocket) { 718 if ((entry->sfe_flags & SFEF_ATTACHED) 719 && entry->sfe_filter->sf_filter.sf_getsockname) { 720 // Retain the filter entry and release the socket filter lock 721 sflt_entry_retain(entry); 722 lck_rw_unlock_shared(sock_filter_lock); 723 724 // If the socket isn't already unlocked, unlock it 725 if (unlocked == 0) { 726 socket_unlock(so, 0); 727 unlocked = 1; 728 } 729 730 // Call the filter 731 error = entry->sfe_filter->sf_filter. 732 sf_getsockname(entry->sfe_cookie, so, local); 733 734 // Take the socket filter lock again and release the entry 735 lck_rw_lock_shared(sock_filter_lock); 736 sflt_entry_release(entry); 737 } 738 } 739 lck_rw_unlock_shared(sock_filter_lock); 740 741 if (unlocked) { 742 socket_lock(so, 0); 743 } 744 745 return error; 746} 747 748__private_extern__ int 749sflt_getpeername( 750 struct socket *so, 751 struct sockaddr **remote) 752{ 753 if (so->so_filt == NULL) return 0; 754 755 struct socket_filter_entry *entry; 756 int unlocked = 0; 757 int error = 0; 758 759 lck_rw_lock_shared(sock_filter_lock); 760 for (entry = so->so_filt; entry && error == 0; 761 entry = entry->sfe_next_onsocket) { 762 if ((entry->sfe_flags & SFEF_ATTACHED) 763 && entry->sfe_filter->sf_filter.sf_getpeername) { 764 // Retain the filter entry and release the socket filter lock 765 sflt_entry_retain(entry); 766 lck_rw_unlock_shared(sock_filter_lock); 767 768 // If the socket isn't already unlocked, unlock it 769 if (unlocked == 0) { 770 socket_unlock(so, 0); 771 unlocked = 1; 772 } 773 774 // Call the filter 775 error = entry->sfe_filter->sf_filter. 776 sf_getpeername(entry->sfe_cookie, so, remote); 777 778 // Take the socket filter lock again and release the entry 779 lck_rw_lock_shared(sock_filter_lock); 780 sflt_entry_release(entry); 781 } 782 } 783 lck_rw_unlock_shared(sock_filter_lock); 784 785 if (unlocked) { 786 socket_lock(so, 0); 787 } 788 789 return error; 790} 791 792__private_extern__ int 793sflt_connectin( 794 struct socket *so, 795 const struct sockaddr *remote) 796{ 797 if (so->so_filt == NULL) return 0; 798 799 struct socket_filter_entry *entry; 800 int unlocked = 0; 801 int error = 0; 802 803 lck_rw_lock_shared(sock_filter_lock); 804 for (entry = so->so_filt; entry && error == 0; 805 entry = entry->sfe_next_onsocket) { 806 if ((entry->sfe_flags & SFEF_ATTACHED) 807 && entry->sfe_filter->sf_filter.sf_connect_in) { 808 // Retain the filter entry and release the socket filter lock 809 sflt_entry_retain(entry); 810 lck_rw_unlock_shared(sock_filter_lock); 811 812 // If the socket isn't already unlocked, unlock it 813 if (unlocked == 0) { 814 socket_unlock(so, 0); 815 unlocked = 1; 816 } 817 818 // Call the filter 819 error = entry->sfe_filter->sf_filter. 820 sf_connect_in(entry->sfe_cookie, so, remote); 821 822 // Take the socket filter lock again and release the entry 823 lck_rw_lock_shared(sock_filter_lock); 824 sflt_entry_release(entry); 825 } 826 } 827 lck_rw_unlock_shared(sock_filter_lock); 828 829 if (unlocked) { 830 socket_lock(so, 0); 831 } 832 833 return error; 834} 835 836__private_extern__ int 837sflt_connectout( 838 struct socket *so, 839 const struct sockaddr *nam) 840{ 841 if (so->so_filt == NULL) return 0; 842 843 struct socket_filter_entry *entry; 844 int unlocked = 0; 845 int error = 0; 846 847 lck_rw_lock_shared(sock_filter_lock); 848 for (entry = so->so_filt; entry && error == 0; 849 entry = entry->sfe_next_onsocket) { 850 if ((entry->sfe_flags & SFEF_ATTACHED) 851 && entry->sfe_filter->sf_filter.sf_connect_out) { 852 // Retain the filter entry and release the socket filter lock 853 sflt_entry_retain(entry); 854 lck_rw_unlock_shared(sock_filter_lock); 855 856 // If the socket isn't already unlocked, unlock it 857 if (unlocked == 0) { 858 socket_unlock(so, 0); 859 unlocked = 1; 860 } 861 862 // Call the filter 863 error = entry->sfe_filter->sf_filter. 864 sf_connect_out(entry->sfe_cookie, so, nam); 865 866 // Take the socket filter lock again and release the entry 867 lck_rw_lock_shared(sock_filter_lock); 868 sflt_entry_release(entry); 869 } 870 } 871 lck_rw_unlock_shared(sock_filter_lock); 872 873 if (unlocked) { 874 socket_lock(so, 0); 875 } 876 877 return error; 878} 879 880__private_extern__ int 881sflt_setsockopt( 882 struct socket *so, 883 struct sockopt *sopt) 884{ 885 if (so->so_filt == NULL) return 0; 886 887 struct socket_filter_entry *entry; 888 int unlocked = 0; 889 int error = 0; 890 891 lck_rw_lock_shared(sock_filter_lock); 892 for (entry = so->so_filt; entry && error == 0; 893 entry = entry->sfe_next_onsocket) { 894 if ((entry->sfe_flags & SFEF_ATTACHED) 895 && entry->sfe_filter->sf_filter.sf_setoption) { 896 // Retain the filter entry and release the socket filter lock 897 sflt_entry_retain(entry); 898 lck_rw_unlock_shared(sock_filter_lock); 899 900 // If the socket isn't already unlocked, unlock it 901 if (unlocked == 0) { 902 socket_unlock(so, 0); 903 unlocked = 1; 904 } 905 906 // Call the filter 907 error = entry->sfe_filter->sf_filter. 908 sf_setoption(entry->sfe_cookie, so, sopt); 909 910 // Take the socket filter lock again and release the entry 911 lck_rw_lock_shared(sock_filter_lock); 912 sflt_entry_release(entry); 913 } 914 } 915 lck_rw_unlock_shared(sock_filter_lock); 916 917 if (unlocked) { 918 socket_lock(so, 0); 919 } 920 921 return error; 922} 923 924__private_extern__ int 925sflt_getsockopt( 926 struct socket *so, 927 struct sockopt *sopt) 928{ 929 if (so->so_filt == NULL) return 0; 930 931 struct socket_filter_entry *entry; 932 int unlocked = 0; 933 int error = 0; 934 935 lck_rw_lock_shared(sock_filter_lock); 936 for (entry = so->so_filt; entry && error == 0; 937 entry = entry->sfe_next_onsocket) { 938 if ((entry->sfe_flags & SFEF_ATTACHED) 939 && entry->sfe_filter->sf_filter.sf_getoption) { 940 // Retain the filter entry and release the socket filter lock 941 sflt_entry_retain(entry); 942 lck_rw_unlock_shared(sock_filter_lock); 943 944 // If the socket isn't already unlocked, unlock it 945 if (unlocked == 0) { 946 socket_unlock(so, 0); 947 unlocked = 1; 948 } 949 950 // Call the filter 951 error = entry->sfe_filter->sf_filter. 952 sf_getoption(entry->sfe_cookie, so, sopt); 953 954 // Take the socket filter lock again and release the entry 955 lck_rw_lock_shared(sock_filter_lock); 956 sflt_entry_release(entry); 957 } 958 } 959 lck_rw_unlock_shared(sock_filter_lock); 960 961 if (unlocked) { 962 socket_lock(so, 0); 963 } 964 965 return error; 966} 967 968__private_extern__ int 969sflt_data_out( 970 struct socket *so, 971 const struct sockaddr *to, 972 mbuf_t *data, 973 mbuf_t *control, 974 sflt_data_flag_t flags) 975{ 976 if (so->so_filt == NULL) return 0; 977 978 struct socket_filter_entry *entry; 979 int unlocked = 0; 980 int setsendthread = 0; 981 int error = 0; 982 983 lck_rw_lock_shared(sock_filter_lock); 984 for (entry = so->so_filt; entry && error == 0; 985 entry = entry->sfe_next_onsocket) { 986 if ((entry->sfe_flags & SFEF_ATTACHED) 987 && entry->sfe_filter->sf_filter.sf_data_out) { 988 // Retain the filter entry and release the socket filter lock 989 sflt_entry_retain(entry); 990 lck_rw_unlock_shared(sock_filter_lock); 991 992 // If the socket isn't already unlocked, unlock it 993 if (unlocked == 0) { 994 if (so->so_send_filt_thread == NULL) { 995 setsendthread = 1; 996 so->so_send_filt_thread = current_thread(); 997 } 998 socket_unlock(so, 0); 999 unlocked = 1; 1000 } 1001 1002 // Call the filter 1003 error = entry->sfe_filter->sf_filter. 1004 sf_data_out(entry->sfe_cookie, so, to, data, control, flags); 1005 1006 // Take the socket filter lock again and release the entry 1007 lck_rw_lock_shared(sock_filter_lock); 1008 sflt_entry_release(entry); 1009 } 1010 } 1011 lck_rw_unlock_shared(sock_filter_lock); 1012 1013 if (unlocked) { 1014 socket_lock(so, 0); 1015 if (setsendthread) so->so_send_filt_thread = NULL; 1016 } 1017 1018 return error; 1019} 1020 1021__private_extern__ int 1022sflt_data_in( 1023 struct socket *so, 1024 const struct sockaddr *from, 1025 mbuf_t *data, 1026 mbuf_t *control, 1027 sflt_data_flag_t flags) 1028{ 1029 if (so->so_filt == NULL) return 0; 1030 1031 struct socket_filter_entry *entry; 1032 int error = 0; 1033 int unlocked = 0; 1034 1035 lck_rw_lock_shared(sock_filter_lock); 1036 1037 for (entry = so->so_filt; entry && (error == 0); 1038 entry = entry->sfe_next_onsocket) { 1039 if ((entry->sfe_flags & SFEF_ATTACHED) && 1040 entry->sfe_filter->sf_filter.sf_data_in) { 1041 // Retain the filter entry and release the socket filter lock 1042 sflt_entry_retain(entry); 1043 lck_rw_unlock_shared(sock_filter_lock); 1044 1045 // If the socket isn't already unlocked, unlock it 1046 if (unlocked == 0) { 1047 unlocked = 1; 1048 socket_unlock(so, 0); 1049 } 1050 1051 // Call the filter 1052 error = entry->sfe_filter->sf_filter.sf_data_in( 1053 entry->sfe_cookie, so, from, data, control, flags); 1054 1055 // Take the socket filter lock again and release the entry 1056 lck_rw_lock_shared(sock_filter_lock); 1057 sflt_entry_release(entry); 1058 } 1059 } 1060 lck_rw_unlock_shared(sock_filter_lock); 1061 1062 if (unlocked) { 1063 socket_lock(so, 0); 1064 } 1065 1066 return error; 1067} 1068 1069#pragma mark -- KPI -- 1070 1071errno_t 1072sflt_attach( 1073 socket_t socket, 1074 sflt_handle handle) 1075{ 1076 socket_lock(socket, 1); 1077 errno_t result = sflt_attach_internal(socket, handle); 1078 socket_unlock(socket, 1); 1079 return result; 1080} 1081 1082errno_t 1083sflt_detach( 1084 socket_t socket, 1085 sflt_handle handle) 1086{ 1087 struct socket_filter_entry *entry; 1088 errno_t result = 0; 1089 1090 if (socket == NULL || handle == 0) 1091 return EINVAL; 1092 1093 lck_rw_lock_exclusive(sock_filter_lock); 1094 for (entry = socket->so_filt; entry; 1095 entry = entry->sfe_next_onsocket) { 1096 if (entry->sfe_filter->sf_filter.sf_handle == handle && 1097 (entry->sfe_flags & SFEF_ATTACHED) != 0) { 1098 break; 1099 } 1100 } 1101 1102 if (entry != NULL) { 1103 sflt_detach_locked(entry); 1104 } 1105 lck_rw_unlock_exclusive(sock_filter_lock); 1106 1107 return result; 1108} 1109 1110struct solist { 1111 struct solist *next; 1112 struct socket *so; 1113}; 1114 1115errno_t 1116sflt_register( 1117 const struct sflt_filter *filter, 1118 int domain, 1119 int type, 1120 int protocol) 1121{ 1122 struct socket_filter *sock_filt = NULL; 1123 struct socket_filter *match = NULL; 1124 int error = 0; 1125 struct protosw *pr = pffindproto(domain, protocol, type); 1126 unsigned int len; 1127 struct socket *so; 1128 struct inpcb *inp; 1129 struct solist *solisthead = NULL, *solist = NULL; 1130 1131 if (pr == NULL) 1132 return ENOENT; 1133 1134 if (filter->sf_attach == NULL || filter->sf_detach == NULL || 1135 filter->sf_handle == 0 || filter->sf_name == NULL) 1136 return EINVAL; 1137 1138 /* Allocate the socket filter */ 1139 MALLOC(sock_filt, struct socket_filter *, sizeof (*sock_filt), 1140 M_IFADDR, M_WAITOK); 1141 if (sock_filt == NULL) { 1142 return ENOBUFS; 1143 } 1144 1145 bzero(sock_filt, sizeof (*sock_filt)); 1146 1147 /* Legacy sflt_filter length; current structure minus extended */ 1148 len = sizeof (*filter) - sizeof (struct sflt_filter_ext); 1149 /* 1150 * Include extended fields if filter defines SFLT_EXTENDED. 1151 * We've zeroed out our internal sflt_filter placeholder, 1152 * so any unused portion would have been taken care of. 1153 */ 1154 if (filter->sf_flags & SFLT_EXTENDED) { 1155 unsigned int ext_len = filter->sf_len; 1156 1157 if (ext_len > sizeof (struct sflt_filter_ext)) 1158 ext_len = sizeof (struct sflt_filter_ext); 1159 1160 len += ext_len; 1161 } 1162 bcopy(filter, &sock_filt->sf_filter, len); 1163 1164 lck_rw_lock_exclusive(sock_filter_lock); 1165 /* Look for an existing entry */ 1166 TAILQ_FOREACH(match, &sock_filter_head, sf_global_next) { 1167 if (match->sf_filter.sf_handle == 1168 sock_filt->sf_filter.sf_handle) { 1169 break; 1170 } 1171 } 1172 1173 /* Add the entry only if there was no existing entry */ 1174 if (match == NULL) { 1175 TAILQ_INSERT_TAIL(&sock_filter_head, sock_filt, sf_global_next); 1176 if ((sock_filt->sf_filter.sf_flags & SFLT_GLOBAL) != 0) { 1177 TAILQ_INSERT_TAIL(&pr->pr_filter_head, sock_filt, 1178 sf_protosw_next); 1179 sock_filt->sf_proto = pr; 1180 } 1181 sflt_retain_locked(sock_filt); 1182 } 1183 lck_rw_unlock_exclusive(sock_filter_lock); 1184 1185 if (match != NULL) { 1186 FREE(sock_filt, M_IFADDR); 1187 return EEXIST; 1188 } 1189 1190 if (!(filter->sf_flags & SFLT_EXTENDED_REGISTRY)) 1191 return error; 1192 1193 /* 1194 * Setup the filter on the TCP and UDP sockets already created. 1195 */ 1196#define SOLIST_ADD(_so) do { \ 1197 solist->next = solisthead; \ 1198 sock_retain((_so)); \ 1199 solist->so = (_so); \ 1200 solisthead = solist; \ 1201} while (0) 1202 if (protocol == IPPROTO_TCP) { 1203 lck_rw_lock_shared(tcbinfo.mtx); 1204 LIST_FOREACH(inp, tcbinfo.listhead, inp_list) { 1205 so = inp->inp_socket; 1206 if (so == NULL || so->so_state & SS_DEFUNCT || 1207 so->so_state & SS_NOFDREF || 1208 !INP_CHECK_SOCKAF(so, domain) || 1209 !INP_CHECK_SOCKTYPE(so, type)) 1210 continue; 1211 MALLOC(solist, struct solist *, sizeof(*solist), 1212 M_IFADDR, M_NOWAIT); 1213 if (!solist) 1214 continue; 1215 SOLIST_ADD(so); 1216 } 1217 lck_rw_done(tcbinfo.mtx); 1218 } else if (protocol == IPPROTO_UDP) { 1219 lck_rw_lock_shared(udbinfo.mtx); 1220 LIST_FOREACH(inp, udbinfo.listhead, inp_list) { 1221 so = inp->inp_socket; 1222 if (so == NULL || so->so_state & SS_DEFUNCT || 1223 so->so_state & SS_NOFDREF || 1224 !INP_CHECK_SOCKAF(so, domain) || 1225 !INP_CHECK_SOCKTYPE(so, type)) 1226 continue; 1227 MALLOC(solist, struct solist *, sizeof(*solist), 1228 M_IFADDR, M_NOWAIT); 1229 if (!solist) 1230 continue; 1231 SOLIST_ADD(so); 1232 } 1233 lck_rw_done(udbinfo.mtx); 1234 } 1235 /* XXX it's possible to walk the raw socket list as well */ 1236#undef SOLIST_ADD 1237 1238 while (solisthead) { 1239 sflt_handle handle = filter->sf_handle; 1240 1241 so = solisthead->so; 1242 sflt_initsock(so); 1243 1244 if (so->so_state & SS_ISCONNECTING) 1245 sflt_notify_after_register(so, sock_evt_connecting, 1246 handle); 1247 else if (so->so_state & SS_ISCONNECTED) 1248 sflt_notify_after_register(so, sock_evt_connected, 1249 handle); 1250 else if ((so->so_state & 1251 (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE)) == 1252 (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE)) 1253 sflt_notify_after_register(so, sock_evt_disconnecting, 1254 handle); 1255 else if ((so->so_state & 1256 (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED)) == 1257 (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED)) 1258 sflt_notify_after_register(so, sock_evt_disconnected, 1259 handle); 1260 else if (so->so_state & SS_CANTSENDMORE) 1261 sflt_notify_after_register(so, sock_evt_cantsendmore, 1262 handle); 1263 else if (so->so_state & SS_CANTRCVMORE) 1264 sflt_notify_after_register(so, sock_evt_cantrecvmore, 1265 handle); 1266 /* XXX no easy way to post the sock_evt_closing event */ 1267 sock_release(so); 1268 solist = solisthead; 1269 solisthead = solisthead->next; 1270 FREE(solist, M_IFADDR); 1271 } 1272 1273 return error; 1274} 1275 1276errno_t 1277sflt_unregister( 1278 sflt_handle handle) 1279{ 1280 struct socket_filter *filter; 1281 lck_rw_lock_exclusive(sock_filter_lock); 1282 1283 /* Find the entry by the handle */ 1284 TAILQ_FOREACH(filter, &sock_filter_head, sf_global_next) { 1285 if (filter->sf_filter.sf_handle == handle) 1286 break; 1287 } 1288 1289 if (filter) { 1290 // Remove it from the global list 1291 TAILQ_REMOVE(&sock_filter_head, filter, sf_global_next); 1292 1293 // Remove it from the protosw list 1294 if ((filter->sf_filter.sf_flags & SFLT_GLOBAL) != 0) { 1295 TAILQ_REMOVE(&filter->sf_proto->pr_filter_head, filter, sf_protosw_next); 1296 } 1297 1298 // Detach from any sockets 1299 struct socket_filter_entry *entry = NULL; 1300 1301 for (entry = filter->sf_entry_head; entry; entry = entry->sfe_next_onfilter) { 1302 sflt_detach_locked(entry); 1303 } 1304 1305 // Release the filter 1306 sflt_release_locked(filter); 1307 } 1308 1309 lck_rw_unlock_exclusive(sock_filter_lock); 1310 1311 if (filter == NULL) 1312 return ENOENT; 1313 1314 return 0; 1315} 1316 1317errno_t 1318sock_inject_data_in( 1319 socket_t so, 1320 const struct sockaddr* from, 1321 mbuf_t data, 1322 mbuf_t control, 1323 sflt_data_flag_t flags) 1324{ 1325 int error = 0; 1326 if (so == NULL || data == NULL) return EINVAL; 1327 1328 if (flags & sock_data_filt_flag_oob) { 1329 return ENOTSUP; 1330 } 1331 1332 socket_lock(so, 1); 1333 1334 if (from) { 1335 if (sbappendaddr(&so->so_rcv, (struct sockaddr*)(uintptr_t)from, data, 1336 control, NULL)) 1337 sorwakeup(so); 1338 goto done; 1339 } 1340 1341 if (control) { 1342 if (sbappendcontrol(&so->so_rcv, data, control, NULL)) 1343 sorwakeup(so); 1344 goto done; 1345 } 1346 1347 if (flags & sock_data_filt_flag_record) { 1348 if (control || from) { 1349 error = EINVAL; 1350 goto done; 1351 } 1352 if (sbappendrecord(&so->so_rcv, (struct mbuf*)data)) 1353 sorwakeup(so); 1354 goto done; 1355 } 1356 1357 if (sbappend(&so->so_rcv, data)) 1358 sorwakeup(so); 1359done: 1360 socket_unlock(so, 1); 1361 return error; 1362} 1363 1364errno_t 1365sock_inject_data_out( 1366 socket_t so, 1367 const struct sockaddr* to, 1368 mbuf_t data, 1369 mbuf_t control, 1370 sflt_data_flag_t flags) 1371{ 1372 int sosendflags = 0; 1373 if (flags & sock_data_filt_flag_oob) sosendflags = MSG_OOB; 1374 return sosend(so, (struct sockaddr*)(uintptr_t)to, NULL, 1375 data, control, sosendflags); 1376} 1377 1378sockopt_dir 1379sockopt_direction( 1380 sockopt_t sopt) 1381{ 1382 return (sopt->sopt_dir == SOPT_GET) ? sockopt_get : sockopt_set; 1383} 1384 1385int 1386sockopt_level( 1387 sockopt_t sopt) 1388{ 1389 return sopt->sopt_level; 1390} 1391 1392int 1393sockopt_name( 1394 sockopt_t sopt) 1395{ 1396 return sopt->sopt_name; 1397} 1398 1399size_t 1400sockopt_valsize( 1401 sockopt_t sopt) 1402{ 1403 return sopt->sopt_valsize; 1404} 1405 1406errno_t 1407sockopt_copyin( 1408 sockopt_t sopt, 1409 void *data, 1410 size_t len) 1411{ 1412 return sooptcopyin(sopt, data, len, len); 1413} 1414 1415errno_t 1416sockopt_copyout( 1417 sockopt_t sopt, 1418 void *data, 1419 size_t len) 1420{ 1421 return sooptcopyout(sopt, data, len); 1422} 1423