1 /*
2 * Copyright (c) 2003-2021 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 <net/net_api_stats.h>
44 #if SKYWALK
45 #include <skywalk/lib/net_filter_event.h>
46 #endif /* SKYWALK */
47 #include <netinet/in_var.h>
48 #include <netinet/ip.h>
49 #include <netinet/ip_var.h>
50 #include <netinet/tcp.h>
51 #include <netinet/tcp_var.h>
52 #include <netinet/udp.h>
53 #include <netinet/udp_var.h>
54
55 #include <libkern/libkern.h>
56 #include <libkern/OSAtomic.h>
57
58 #include <libkern/sysctl.h>
59 #include <libkern/OSDebug.h>
60
61 #include <os/refcnt.h>
62
63 #include <stdbool.h>
64 #include <string.h>
65
66 #if SKYWALK
67 #include <skywalk/core/skywalk_var.h>
68 #endif /* SKYWALK */
69
70 #include <net/sockaddr_utils.h>
71
72 #define SFEF_ATTACHED 0x1 /* SFE is on socket list */
73 #define SFEF_NODETACH 0x2 /* Detach should not be called */
74 #define SFEF_NOSOCKET 0x4 /* Socket is gone */
75
76 struct socket_filter_entry {
77 struct socket_filter_entry *sfe_next_onsocket;
78 struct socket_filter_entry *sfe_next_onfilter;
79 struct socket_filter_entry *sfe_next_oncleanup;
80
81 struct socket_filter *sfe_filter;
82 struct socket *sfe_socket;
83 void *sfe_cookie;
84
85 uint32_t sfe_flags;
86 struct os_refcnt sfe_refcount;
87 };
88
89 struct socket_filter {
90 TAILQ_ENTRY(socket_filter) sf_protosw_next;
91 TAILQ_ENTRY(socket_filter) sf_global_next;
92 struct socket_filter_entry *sf_entry_head;
93
94 struct protosw *sf_proto;
95 struct sflt_filter sf_filter;
96 struct os_refcnt sf_refcount;
97 uint32_t sf_flags;
98 };
99
100 #define SFF_INTERNAL 0x1
101
102 TAILQ_HEAD(socket_filter_list, socket_filter);
103
104 static LCK_GRP_DECLARE(sock_filter_lock_grp, "socket filter lock");
105 static LCK_RW_DECLARE(sock_filter_lock, &sock_filter_lock_grp);
106 static LCK_MTX_DECLARE(sock_filter_cleanup_lock, &sock_filter_lock_grp);
107
108 static struct socket_filter_list sock_filter_head =
109 TAILQ_HEAD_INITIALIZER(sock_filter_head);
110 static struct socket_filter_entry *sock_filter_cleanup_entries = NULL;
111 static thread_t sock_filter_cleanup_thread = NULL;
112
113 static void sflt_cleanup_thread(void *, wait_result_t);
114 static void sflt_detach_locked(struct socket_filter_entry *entry);
115
116 #undef sflt_register
117 static errno_t sflt_register_common(const struct sflt_filter *filter, int domain,
118 int type, int protocol, bool is_internal);
119 errno_t sflt_register(const struct sflt_filter *filter, int domain,
120 int type, int protocol);
121
122 #if SKYWALK
123 static bool net_check_compatible_sfltr(void);
124 bool net_check_compatible_alf(void);
125 static bool net_check_compatible_parental_controls(void);
126 #endif /* SKYWALK */
127
128 #pragma mark -- Internal State Management --
129
130 __private_extern__ int
sflt_permission_check(struct inpcb * inp)131 sflt_permission_check(struct inpcb *inp)
132 {
133 /* Only IPv4 or IPv6 sockets can bypass filters */
134 if (!(inp->inp_vflag & INP_IPV4) &&
135 !(inp->inp_vflag & INP_IPV6)) {
136 return 0;
137 }
138 /* Sockets that have incoproc or management entitlements bypass socket filters. */
139 if (INP_INTCOPROC_ALLOWED(inp) || INP_MANAGEMENT_ALLOWED(inp)) {
140 return 1;
141 }
142 /* Sockets bound to an intcoproc or management interface bypass socket filters. */
143 if ((inp->inp_flags & INP_BOUND_IF) &&
144 (IFNET_IS_INTCOPROC(inp->inp_boundifp) ||
145 IFNET_IS_MANAGEMENT(inp->inp_boundifp))) {
146 return 1;
147 }
148 #if NECP
149 /*
150 * Make sure that the NECP policy is populated.
151 * If result is not populated, the policy ID will be
152 * NECP_KERNEL_POLICY_ID_NONE. Note that if the result
153 * is populated, but there was no match, it will be
154 * NECP_KERNEL_POLICY_ID_NO_MATCH.
155 * Do not call inp_update_necp_policy() to avoid scoping
156 * a socket prior to calls to bind().
157 */
158 if (inp->inp_policyresult.policy_id == NECP_KERNEL_POLICY_ID_NONE) {
159 necp_socket_find_policy_match(inp, NULL, NULL, 0);
160 }
161
162 /* If the filter unit is marked to be "no filter", bypass filters */
163 if (inp->inp_policyresult.results.filter_control_unit ==
164 NECP_FILTER_UNIT_NO_FILTER) {
165 return 1;
166 }
167 #endif /* NECP */
168 return 0;
169 }
170
171 static void
sflt_retain_locked(struct socket_filter * filter)172 sflt_retain_locked(struct socket_filter *filter)
173 {
174 os_ref_retain_locked(&filter->sf_refcount);
175 }
176
177 static void
sflt_release_locked(struct socket_filter * filter)178 sflt_release_locked(struct socket_filter *filter)
179 {
180 if (os_ref_release_locked(&filter->sf_refcount) == 0) {
181 /* Call the unregistered function */
182 if (filter->sf_filter.sf_unregistered) {
183 lck_rw_unlock_exclusive(&sock_filter_lock);
184 filter->sf_filter.sf_unregistered(
185 filter->sf_filter.sf_handle);
186 lck_rw_lock_exclusive(&sock_filter_lock);
187 }
188
189 /* Free the entry */
190 kfree_type(struct socket_filter, filter);
191 }
192 }
193
194 static void
sflt_entry_retain(struct socket_filter_entry * entry)195 sflt_entry_retain(struct socket_filter_entry *entry)
196 {
197 os_ref_retain(&entry->sfe_refcount);
198 }
199
200 static void
sflt_entry_release(struct socket_filter_entry * entry)201 sflt_entry_release(struct socket_filter_entry *entry)
202 {
203 if (os_ref_release(&entry->sfe_refcount) == 0) {
204 /* That was the last reference */
205
206 /* Take the cleanup lock */
207 lck_mtx_lock(&sock_filter_cleanup_lock);
208
209 /* Put this item on the cleanup list */
210 entry->sfe_next_oncleanup = sock_filter_cleanup_entries;
211 sock_filter_cleanup_entries = entry;
212
213 /* If the item is the first item in the list */
214 if (entry->sfe_next_oncleanup == NULL) {
215 if (sock_filter_cleanup_thread == NULL) {
216 /* Create a thread */
217 kernel_thread_start(sflt_cleanup_thread,
218 NULL, &sock_filter_cleanup_thread);
219 } else {
220 /* Wakeup the thread */
221 wakeup(&sock_filter_cleanup_entries);
222 }
223 }
224
225 /* Drop the cleanup lock */
226 lck_mtx_unlock(&sock_filter_cleanup_lock);
227 }
228 }
229
230 __attribute__((noreturn))
231 static void
sflt_cleanup_thread(void * blah,wait_result_t blah2)232 sflt_cleanup_thread(void *blah, wait_result_t blah2)
233 {
234 #pragma unused(blah, blah2)
235 while (1) {
236 lck_mtx_lock(&sock_filter_cleanup_lock);
237 while (sock_filter_cleanup_entries == NULL) {
238 /* Sleep until we've got something better to do */
239 msleep(&sock_filter_cleanup_entries,
240 &sock_filter_cleanup_lock, PWAIT,
241 "sflt_cleanup", NULL);
242 }
243
244 /* Pull the current list of dead items */
245 struct socket_filter_entry *dead = sock_filter_cleanup_entries;
246 sock_filter_cleanup_entries = NULL;
247
248 /* Drop the lock */
249 lck_mtx_unlock(&sock_filter_cleanup_lock);
250
251 /* Take the socket filter lock */
252 lck_rw_lock_exclusive(&sock_filter_lock);
253
254 /* Cleanup every dead item */
255 struct socket_filter_entry *__single entry;
256 for (entry = dead; entry; entry = dead) {
257 struct socket_filter_entry **__single nextpp;
258
259 dead = entry->sfe_next_oncleanup;
260
261 /* Call detach function if necessary - drop the lock */
262 if ((entry->sfe_flags & SFEF_NODETACH) == 0 &&
263 entry->sfe_filter->sf_filter.sf_detach) {
264 entry->sfe_flags |= SFEF_NODETACH;
265 lck_rw_unlock_exclusive(&sock_filter_lock);
266
267 /*
268 * Warning - passing a potentially
269 * dead socket may be bad
270 */
271 entry->sfe_filter->sf_filter.sf_detach(
272 entry->sfe_cookie, entry->sfe_socket);
273
274 lck_rw_lock_exclusive(&sock_filter_lock);
275 }
276
277 /*
278 * Pull entry off the socket list --
279 * if the socket still exists
280 */
281 if ((entry->sfe_flags & SFEF_NOSOCKET) == 0) {
282 for (nextpp = &entry->sfe_socket->so_filt;
283 *nextpp;
284 nextpp = &(*nextpp)->sfe_next_onsocket) {
285 if (*nextpp == entry) {
286 *nextpp =
287 entry->sfe_next_onsocket;
288 break;
289 }
290 }
291 }
292
293 /* Pull entry off the filter list */
294 for (nextpp = &entry->sfe_filter->sf_entry_head;
295 *nextpp; nextpp = &(*nextpp)->sfe_next_onfilter) {
296 if (*nextpp == entry) {
297 *nextpp = entry->sfe_next_onfilter;
298 break;
299 }
300 }
301
302 /*
303 * Release the filter -- may drop lock, but that's okay
304 */
305 sflt_release_locked(entry->sfe_filter);
306 entry->sfe_socket = NULL;
307 entry->sfe_filter = NULL;
308 kfree_type(struct socket_filter_entry, entry);
309 }
310
311 /* Drop the socket filter lock */
312 lck_rw_unlock_exclusive(&sock_filter_lock);
313 }
314 /* NOTREACHED */
315 }
316
317 static int
sflt_attach_locked(struct socket * so,struct socket_filter * filter,int socklocked)318 sflt_attach_locked(struct socket *so, struct socket_filter *filter,
319 int socklocked)
320 {
321 int error = 0;
322 struct socket_filter_entry *__single entry = NULL;
323
324 if (sflt_permission_check(sotoinpcb(so))) {
325 return 0;
326 }
327
328 if (filter == NULL) {
329 return ENOENT;
330 }
331
332 for (entry = so->so_filt; entry; entry = entry->sfe_next_onfilter) {
333 if (entry->sfe_filter->sf_filter.sf_handle ==
334 filter->sf_filter.sf_handle) {
335 return EEXIST;
336 }
337 }
338 /* allocate the socket filter entry */
339 entry = kalloc_type(struct socket_filter_entry, Z_WAITOK | Z_NOFAIL);
340
341 /* Initialize the socket filter entry */
342 entry->sfe_cookie = NULL;
343 entry->sfe_flags = SFEF_ATTACHED;
344 os_ref_init(&entry->sfe_refcount, NULL); /* corresponds to SFEF_ATTACHED flag set */
345
346 /* Put the entry in the filter list */
347 sflt_retain_locked(filter);
348 entry->sfe_filter = filter;
349 entry->sfe_next_onfilter = filter->sf_entry_head;
350 filter->sf_entry_head = entry;
351
352 /* Put the entry on the socket filter list */
353 entry->sfe_socket = so;
354 entry->sfe_next_onsocket = so->so_filt;
355 so->so_filt = entry;
356
357 if (entry->sfe_filter->sf_filter.sf_attach) {
358 /* Retain the entry while we call attach */
359 sflt_entry_retain(entry);
360
361 /*
362 * Release the filter lock --
363 * callers must be aware we will do this
364 */
365 lck_rw_unlock_exclusive(&sock_filter_lock);
366
367 /* Unlock the socket */
368 if (socklocked) {
369 socket_unlock(so, 0);
370 }
371
372 /* It's finally safe to call the filter function */
373 error = entry->sfe_filter->sf_filter.sf_attach(
374 &entry->sfe_cookie, so);
375
376 /* Lock the socket again */
377 if (socklocked) {
378 socket_lock(so, 0);
379 }
380
381 /* Lock the filters again */
382 lck_rw_lock_exclusive(&sock_filter_lock);
383
384 /*
385 * If the attach function returns an error,
386 * this filter must be detached
387 */
388 if (error) {
389 /* don't call sf_detach */
390 entry->sfe_flags |= SFEF_NODETACH;
391 sflt_detach_locked(entry);
392 }
393
394 /* Release the retain we held through the attach call */
395 sflt_entry_release(entry);
396 }
397
398 return error;
399 }
400
401 errno_t
sflt_attach_internal(socket_t socket,sflt_handle handle)402 sflt_attach_internal(socket_t socket, sflt_handle handle)
403 {
404 if (socket == NULL || handle == 0) {
405 return EINVAL;
406 }
407
408 int result = EINVAL;
409
410 lck_rw_lock_exclusive(&sock_filter_lock);
411
412 struct socket_filter *__single filter = NULL;
413 TAILQ_FOREACH(filter, &sock_filter_head, sf_global_next) {
414 if (filter->sf_filter.sf_handle == handle) {
415 break;
416 }
417 }
418
419 if (filter) {
420 result = sflt_attach_locked(socket, filter, 1);
421 }
422
423 lck_rw_unlock_exclusive(&sock_filter_lock);
424
425 return result;
426 }
427
428 static void
sflt_detach_locked(struct socket_filter_entry * entry)429 sflt_detach_locked(struct socket_filter_entry *entry)
430 {
431 if ((entry->sfe_flags & SFEF_ATTACHED) != 0) {
432 entry->sfe_flags &= ~SFEF_ATTACHED;
433 sflt_entry_release(entry);
434 }
435 }
436
437 #pragma mark -- Socket Layer Hooks --
438
439 __private_extern__ void
sflt_initsock(struct socket * so)440 sflt_initsock(struct socket *so)
441 {
442 /*
443 * Can only register socket filter for internet protocols
444 */
445 if (SOCK_DOM(so) != PF_INET && SOCK_DOM(so) != PF_INET6) {
446 return;
447 }
448
449 /*
450 * Point to the real protosw, as so_proto might have been
451 * pointed to a modified version.
452 */
453 struct protosw *__single proto = so->so_proto->pr_protosw;
454
455 lck_rw_lock_shared(&sock_filter_lock);
456 if (TAILQ_FIRST(&proto->pr_filter_head) != NULL) {
457 /* Promote lock to exclusive */
458 if (!lck_rw_lock_shared_to_exclusive(&sock_filter_lock)) {
459 lck_rw_lock_exclusive(&sock_filter_lock);
460 }
461
462 /*
463 * Warning: A filter unregistering will be pulled out of
464 * the list. This could happen while we drop the lock in
465 * sftl_attach_locked or sflt_release_locked. For this
466 * reason we retain a reference on the filter (or next_filter)
467 * while calling this function. This protects us from a panic,
468 * but it could result in a socket being created without all
469 * of the global filters if we're attaching a filter as it
470 * is removed, if that's possible.
471 */
472 struct socket_filter *__single filter =
473 TAILQ_FIRST(&proto->pr_filter_head);
474
475 sflt_retain_locked(filter);
476
477 while (filter) {
478 struct socket_filter *__single filter_next;
479 /*
480 * Warning: sflt_attach_private_locked
481 * will drop the lock
482 */
483 sflt_attach_locked(so, filter, 0);
484
485 filter_next = TAILQ_NEXT(filter, sf_protosw_next);
486 if (filter_next) {
487 sflt_retain_locked(filter_next);
488 }
489
490 /*
491 * Warning: filt_release_locked may remove
492 * the filter from the queue
493 */
494 sflt_release_locked(filter);
495 filter = filter_next;
496 }
497 }
498 lck_rw_done(&sock_filter_lock);
499 }
500
501 /*
502 * sflt_termsock
503 *
504 * Detaches all filters from the socket.
505 */
506 __private_extern__ void
sflt_termsock(struct socket * so)507 sflt_termsock(struct socket *so)
508 {
509 /*
510 * Fast path to avoid taking the lock
511 */
512 if (so->so_filt == NULL) {
513 return;
514 }
515
516 lck_rw_lock_exclusive(&sock_filter_lock);
517
518 struct socket_filter_entry *__single entry;
519
520 while ((entry = so->so_filt) != NULL) {
521 /* Pull filter off the socket */
522 so->so_filt = entry->sfe_next_onsocket;
523 entry->sfe_flags |= SFEF_NOSOCKET;
524
525 /* Call detach */
526 sflt_detach_locked(entry);
527
528 /*
529 * On sflt_termsock, we can't return until the detach function
530 * has been called. Call the detach function - this is gross
531 * because the socket filter entry could be freed when we drop
532 * the lock, so we make copies on the stack and retain
533 * everything we need before dropping the lock.
534 */
535 if ((entry->sfe_flags & SFEF_NODETACH) == 0 &&
536 entry->sfe_filter->sf_filter.sf_detach) {
537 void *__single sfe_cookie = entry->sfe_cookie;
538 struct socket_filter *__single sfe_filter = entry->sfe_filter;
539
540 /* Retain the socket filter */
541 sflt_retain_locked(sfe_filter);
542
543 /* Mark that we've called the detach function */
544 entry->sfe_flags |= SFEF_NODETACH;
545
546 /* Drop the lock before calling the detach function */
547 lck_rw_unlock_exclusive(&sock_filter_lock);
548 sfe_filter->sf_filter.sf_detach(sfe_cookie, so);
549 lck_rw_lock_exclusive(&sock_filter_lock);
550
551 /* Release the filter */
552 sflt_release_locked(sfe_filter);
553 }
554 }
555
556 lck_rw_unlock_exclusive(&sock_filter_lock);
557 }
558
559
560 static void
sflt_notify_internal(struct socket * so,sflt_event_t event,void * param,sflt_handle handle)561 sflt_notify_internal(struct socket *so, sflt_event_t event, void *param,
562 sflt_handle handle)
563 {
564 if (so->so_filt == NULL) {
565 return;
566 }
567
568 struct socket_filter_entry *__single entry;
569 int unlocked = 0;
570
571 lck_rw_lock_shared(&sock_filter_lock);
572 for (entry = so->so_filt; entry; entry = entry->sfe_next_onsocket) {
573 if ((entry->sfe_flags & SFEF_ATTACHED) &&
574 entry->sfe_filter->sf_filter.sf_notify &&
575 ((handle && entry->sfe_filter->sf_filter.sf_handle !=
576 handle) || !handle)) {
577 /*
578 * Retain the filter entry and release
579 * the socket filter lock
580 */
581 sflt_entry_retain(entry);
582 lck_rw_unlock_shared(&sock_filter_lock);
583
584 /* If the socket isn't already unlocked, unlock it */
585 if (unlocked == 0) {
586 unlocked = 1;
587 socket_unlock(so, 0);
588 }
589
590 /* Finally call the filter */
591 entry->sfe_filter->sf_filter.sf_notify(
592 entry->sfe_cookie, so, event, param);
593
594 /*
595 * Take the socket filter lock again
596 * and release the entry
597 */
598 lck_rw_lock_shared(&sock_filter_lock);
599 sflt_entry_release(entry);
600 }
601 }
602 lck_rw_unlock_shared(&sock_filter_lock);
603
604 if (unlocked != 0) {
605 socket_lock(so, 0);
606 }
607 }
608
609 __private_extern__ void
sflt_notify(struct socket * so,sflt_event_t event,void * param)610 sflt_notify(struct socket *so, sflt_event_t event, void *param)
611 {
612 sflt_notify_internal(so, event, param, 0);
613 }
614
615 static void
sflt_notify_after_register(struct socket * so,sflt_event_t event,sflt_handle handle)616 sflt_notify_after_register(struct socket *so, sflt_event_t event,
617 sflt_handle handle)
618 {
619 sflt_notify_internal(so, event, NULL, handle);
620 }
621
622 __private_extern__ int
sflt_ioctl(struct socket * so,u_long cmd,caddr_t __sized_by (IOCPARM_LEN (cmd))data)623 sflt_ioctl(struct socket *so, u_long cmd, caddr_t __sized_by(IOCPARM_LEN(cmd)) data)
624 {
625 if (so->so_filt == NULL || sflt_permission_check(sotoinpcb(so))) {
626 return 0;
627 }
628
629 struct socket_filter_entry *__single entry;
630 int unlocked = 0;
631 int error = 0;
632
633 lck_rw_lock_shared(&sock_filter_lock);
634 for (entry = so->so_filt; entry && error == 0;
635 entry = entry->sfe_next_onsocket) {
636 if ((entry->sfe_flags & SFEF_ATTACHED) &&
637 entry->sfe_filter->sf_filter.sf_ioctl) {
638 /*
639 * Retain the filter entry and release
640 * the socket filter lock
641 */
642 sflt_entry_retain(entry);
643 lck_rw_unlock_shared(&sock_filter_lock);
644
645 /* If the socket isn't already unlocked, unlock it */
646 if (unlocked == 0) {
647 socket_unlock(so, 0);
648 unlocked = 1;
649 }
650
651 /* Call the filter */
652 error = entry->sfe_filter->sf_filter.sf_ioctl(
653 entry->sfe_cookie, so, cmd, data);
654
655 /*
656 * Take the socket filter lock again
657 * and release the entry
658 */
659 lck_rw_lock_shared(&sock_filter_lock);
660 sflt_entry_release(entry);
661 }
662 }
663 lck_rw_unlock_shared(&sock_filter_lock);
664
665 if (unlocked) {
666 socket_lock(so, 0);
667 }
668
669 return error;
670 }
671
672 __private_extern__ int
sflt_bind(struct socket * so,const struct sockaddr * nam)673 sflt_bind(struct socket *so, const struct sockaddr *nam)
674 {
675 if (so->so_filt == NULL || sflt_permission_check(sotoinpcb(so))) {
676 return 0;
677 }
678
679 struct socket_filter_entry *__single entry;
680 int unlocked = 0;
681 int error = 0;
682
683 lck_rw_lock_shared(&sock_filter_lock);
684 for (entry = so->so_filt; entry && error == 0;
685 entry = entry->sfe_next_onsocket) {
686 if ((entry->sfe_flags & SFEF_ATTACHED) &&
687 entry->sfe_filter->sf_filter.sf_bind) {
688 /*
689 * Retain the filter entry and
690 * release the socket filter lock
691 */
692 sflt_entry_retain(entry);
693 lck_rw_unlock_shared(&sock_filter_lock);
694
695 /* If the socket isn't already unlocked, unlock it */
696 if (unlocked == 0) {
697 socket_unlock(so, 0);
698 unlocked = 1;
699 }
700
701 /* Call the filter */
702 error = entry->sfe_filter->sf_filter.sf_bind(
703 entry->sfe_cookie, so, nam);
704
705 /*
706 * Take the socket filter lock again and
707 * release the entry
708 */
709 lck_rw_lock_shared(&sock_filter_lock);
710 sflt_entry_release(entry);
711 }
712 }
713 lck_rw_unlock_shared(&sock_filter_lock);
714
715 if (unlocked) {
716 socket_lock(so, 0);
717 }
718
719 return error;
720 }
721
722 __private_extern__ int
sflt_listen(struct socket * so)723 sflt_listen(struct socket *so)
724 {
725 if (so->so_filt == NULL || sflt_permission_check(sotoinpcb(so))) {
726 return 0;
727 }
728
729 struct socket_filter_entry *__single entry;
730 int unlocked = 0;
731 int error = 0;
732
733 lck_rw_lock_shared(&sock_filter_lock);
734 for (entry = so->so_filt; entry && error == 0;
735 entry = entry->sfe_next_onsocket) {
736 if ((entry->sfe_flags & SFEF_ATTACHED) &&
737 entry->sfe_filter->sf_filter.sf_listen) {
738 /*
739 * Retain the filter entry and release
740 * the socket filter lock
741 */
742 sflt_entry_retain(entry);
743 lck_rw_unlock_shared(&sock_filter_lock);
744
745 /* If the socket isn't already unlocked, unlock it */
746 if (unlocked == 0) {
747 socket_unlock(so, 0);
748 unlocked = 1;
749 }
750
751 /* Call the filter */
752 error = entry->sfe_filter->sf_filter.sf_listen(
753 entry->sfe_cookie, so);
754
755 /*
756 * Take the socket filter lock again
757 * and release the entry
758 */
759 lck_rw_lock_shared(&sock_filter_lock);
760 sflt_entry_release(entry);
761 }
762 }
763 lck_rw_unlock_shared(&sock_filter_lock);
764
765 if (unlocked) {
766 socket_lock(so, 0);
767 }
768
769 return error;
770 }
771
772 __private_extern__ int
sflt_accept(struct socket * head,struct socket * so,const struct sockaddr * local,const struct sockaddr * remote)773 sflt_accept(struct socket *head, struct socket *so,
774 const struct sockaddr *local, const struct sockaddr *remote)
775 {
776 if (so->so_filt == NULL || sflt_permission_check(sotoinpcb(so))) {
777 return 0;
778 }
779
780 struct socket_filter_entry *__single entry;
781 int unlocked = 0;
782 int error = 0;
783
784 lck_rw_lock_shared(&sock_filter_lock);
785 for (entry = so->so_filt; entry && error == 0;
786 entry = entry->sfe_next_onsocket) {
787 if ((entry->sfe_flags & SFEF_ATTACHED) &&
788 entry->sfe_filter->sf_filter.sf_accept) {
789 /*
790 * Retain the filter entry and
791 * release the socket filter lock
792 */
793 sflt_entry_retain(entry);
794 lck_rw_unlock_shared(&sock_filter_lock);
795
796 /* If the socket isn't already unlocked, unlock it */
797 if (unlocked == 0) {
798 socket_unlock(so, 0);
799 unlocked = 1;
800 }
801
802 /* Call the filter */
803 error = entry->sfe_filter->sf_filter.sf_accept(
804 entry->sfe_cookie, head, so, local, remote);
805
806 /*
807 * Take the socket filter lock again
808 * and release the entry
809 */
810 lck_rw_lock_shared(&sock_filter_lock);
811 sflt_entry_release(entry);
812 }
813 }
814 lck_rw_unlock_shared(&sock_filter_lock);
815
816 if (unlocked) {
817 socket_lock(so, 0);
818 }
819
820 return error;
821 }
822
823 __private_extern__ int
sflt_getsockname(struct socket * so,struct sockaddr ** local)824 sflt_getsockname(struct socket *so, struct sockaddr **local)
825 {
826 if (so->so_filt == NULL || sflt_permission_check(sotoinpcb(so))) {
827 return 0;
828 }
829
830 struct socket_filter_entry *__single entry;
831 int unlocked = 0;
832 int error = 0;
833
834 lck_rw_lock_shared(&sock_filter_lock);
835 for (entry = so->so_filt; entry && error == 0;
836 entry = entry->sfe_next_onsocket) {
837 if ((entry->sfe_flags & SFEF_ATTACHED) &&
838 entry->sfe_filter->sf_filter.sf_getsockname) {
839 /*
840 * Retain the filter entry and
841 * release the socket filter lock
842 */
843 sflt_entry_retain(entry);
844 lck_rw_unlock_shared(&sock_filter_lock);
845
846 /* If the socket isn't already unlocked, unlock it */
847 if (unlocked == 0) {
848 socket_unlock(so, 0);
849 unlocked = 1;
850 }
851
852 /* Call the filter */
853 error = entry->sfe_filter->sf_filter.sf_getsockname(
854 entry->sfe_cookie, so, local);
855
856 /*
857 * Take the socket filter lock again
858 * and release the entry
859 */
860 lck_rw_lock_shared(&sock_filter_lock);
861 sflt_entry_release(entry);
862 }
863 }
864 lck_rw_unlock_shared(&sock_filter_lock);
865
866 if (unlocked) {
867 socket_lock(so, 0);
868 }
869
870 return error;
871 }
872
873 __private_extern__ int
sflt_getpeername(struct socket * so,struct sockaddr ** remote)874 sflt_getpeername(struct socket *so, struct sockaddr **remote)
875 {
876 if (so->so_filt == NULL || sflt_permission_check(sotoinpcb(so))) {
877 return 0;
878 }
879
880 struct socket_filter_entry *__single entry;
881 int unlocked = 0;
882 int error = 0;
883
884 lck_rw_lock_shared(&sock_filter_lock);
885 for (entry = so->so_filt; entry && error == 0;
886 entry = entry->sfe_next_onsocket) {
887 if ((entry->sfe_flags & SFEF_ATTACHED) &&
888 entry->sfe_filter->sf_filter.sf_getpeername) {
889 /*
890 * Retain the filter entry and release
891 * the socket filter lock
892 */
893 sflt_entry_retain(entry);
894 lck_rw_unlock_shared(&sock_filter_lock);
895
896 /* If the socket isn't already unlocked, unlock it */
897 if (unlocked == 0) {
898 socket_unlock(so, 0);
899 unlocked = 1;
900 }
901
902 /* Call the filter */
903 error = entry->sfe_filter->sf_filter.sf_getpeername(
904 entry->sfe_cookie, so, remote);
905
906 /*
907 * Take the socket filter lock again
908 * and release the entry
909 */
910 lck_rw_lock_shared(&sock_filter_lock);
911 sflt_entry_release(entry);
912 }
913 }
914 lck_rw_unlock_shared(&sock_filter_lock);
915
916 if (unlocked) {
917 socket_lock(so, 0);
918 }
919
920 return error;
921 }
922
923 __private_extern__ int
sflt_connectin(struct socket * so,const struct sockaddr * remote)924 sflt_connectin(struct socket *so, const struct sockaddr *remote)
925 {
926 if (so->so_filt == NULL || sflt_permission_check(sotoinpcb(so))) {
927 return 0;
928 }
929
930 struct socket_filter_entry *__single entry;
931 int unlocked = 0;
932 int error = 0;
933
934 lck_rw_lock_shared(&sock_filter_lock);
935 for (entry = so->so_filt; entry && error == 0;
936 entry = entry->sfe_next_onsocket) {
937 if ((entry->sfe_flags & SFEF_ATTACHED) &&
938 entry->sfe_filter->sf_filter.sf_connect_in) {
939 /*
940 * Retain the filter entry and release
941 * the socket filter lock
942 */
943 sflt_entry_retain(entry);
944 lck_rw_unlock_shared(&sock_filter_lock);
945
946 /* If the socket isn't already unlocked, unlock it */
947 if (unlocked == 0) {
948 socket_unlock(so, 0);
949 unlocked = 1;
950 }
951
952 /* Call the filter */
953 error = entry->sfe_filter->sf_filter.sf_connect_in(
954 entry->sfe_cookie, so, remote);
955
956 /*
957 * Take the socket filter lock again
958 * and release the entry
959 */
960 lck_rw_lock_shared(&sock_filter_lock);
961 sflt_entry_release(entry);
962 }
963 }
964 lck_rw_unlock_shared(&sock_filter_lock);
965
966 if (unlocked) {
967 socket_lock(so, 0);
968 }
969
970 return error;
971 }
972
973 static int
sflt_connectout_common(struct socket * so,const struct sockaddr * nam)974 sflt_connectout_common(struct socket *so, const struct sockaddr *nam)
975 {
976 struct socket_filter_entry *__single entry;
977 int unlocked = 0;
978 int error = 0;
979
980 lck_rw_lock_shared(&sock_filter_lock);
981 for (entry = so->so_filt; entry && error == 0;
982 entry = entry->sfe_next_onsocket) {
983 if ((entry->sfe_flags & SFEF_ATTACHED) &&
984 entry->sfe_filter->sf_filter.sf_connect_out) {
985 /*
986 * Retain the filter entry and release
987 * the socket filter lock
988 */
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 socket_unlock(so, 0);
995 unlocked = 1;
996 }
997
998 /* Call the filter */
999 error = entry->sfe_filter->sf_filter.sf_connect_out(
1000 entry->sfe_cookie, so, nam);
1001
1002 /*
1003 * Take the socket filter lock again
1004 * and release the entry
1005 */
1006 lck_rw_lock_shared(&sock_filter_lock);
1007 sflt_entry_release(entry);
1008 }
1009 }
1010 lck_rw_unlock_shared(&sock_filter_lock);
1011
1012 if (unlocked) {
1013 socket_lock(so, 0);
1014 }
1015
1016 return error;
1017 }
1018
1019 __private_extern__ int
sflt_connectout(struct socket * so,const struct sockaddr * innam)1020 sflt_connectout(struct socket *so, const struct sockaddr *innam)
1021 {
1022 const struct sockaddr *nam = (const struct sockaddr *__indexable)innam;
1023 char buf[SOCK_MAXADDRLEN];
1024 struct sockaddr *sa;
1025 int error;
1026
1027 if (so->so_filt == NULL || sflt_permission_check(sotoinpcb(so))) {
1028 return 0;
1029 }
1030
1031 /*
1032 * Workaround for rdar://23362120
1033 * Always pass a buffer that can hold an IPv6 socket address
1034 */
1035 bzero(buf, sizeof(buf));
1036 SOCKADDR_COPY(nam, buf, nam->sa_len);
1037 sa = (struct sockaddr *)buf;
1038
1039 error = sflt_connectout_common(so, sa);
1040 if (error != 0) {
1041 return error;
1042 }
1043
1044 /*
1045 * If the address was modified, copy it back
1046 */
1047 if (SOCKADDR_CMP(sa, nam, nam->sa_len) != 0) {
1048 SOCKADDR_COPY(sa, __DECONST_SA(nam), nam->sa_len);
1049 }
1050
1051 return 0;
1052 }
1053
1054 __private_extern__ int
sflt_setsockopt(struct socket * so,struct sockopt * sopt)1055 sflt_setsockopt(struct socket *so, struct sockopt *sopt)
1056 {
1057 if (so->so_filt == NULL || sflt_permission_check(sotoinpcb(so))) {
1058 return 0;
1059 }
1060
1061 /* Socket-options are checked at the MPTCP-layer */
1062 if (so->so_flags & SOF_MP_SUBFLOW) {
1063 return 0;
1064 }
1065
1066 struct socket_filter_entry *__single entry;
1067 int unlocked = 0;
1068 int error = 0;
1069
1070 lck_rw_lock_shared(&sock_filter_lock);
1071 for (entry = so->so_filt; entry && error == 0;
1072 entry = entry->sfe_next_onsocket) {
1073 if ((entry->sfe_flags & SFEF_ATTACHED) &&
1074 entry->sfe_filter->sf_filter.sf_setoption) {
1075 /*
1076 * Retain the filter entry and release
1077 * the socket filter lock
1078 */
1079 sflt_entry_retain(entry);
1080 lck_rw_unlock_shared(&sock_filter_lock);
1081
1082 /* If the socket isn't already unlocked, unlock it */
1083 if (unlocked == 0) {
1084 socket_unlock(so, 0);
1085 unlocked = 1;
1086 }
1087
1088 /* Call the filter */
1089 error = entry->sfe_filter->sf_filter.sf_setoption(
1090 entry->sfe_cookie, so, sopt);
1091
1092 /*
1093 * Take the socket filter lock again
1094 * and release the entry
1095 */
1096 lck_rw_lock_shared(&sock_filter_lock);
1097 sflt_entry_release(entry);
1098 }
1099 }
1100 lck_rw_unlock_shared(&sock_filter_lock);
1101
1102 if (unlocked) {
1103 socket_lock(so, 0);
1104 }
1105
1106 return error;
1107 }
1108
1109 __private_extern__ int
sflt_getsockopt(struct socket * so,struct sockopt * sopt)1110 sflt_getsockopt(struct socket *so, struct sockopt *sopt)
1111 {
1112 if (so->so_filt == NULL || sflt_permission_check(sotoinpcb(so))) {
1113 return 0;
1114 }
1115
1116 /* Socket-options are checked at the MPTCP-layer */
1117 if (so->so_flags & SOF_MP_SUBFLOW) {
1118 return 0;
1119 }
1120
1121 struct socket_filter_entry *__single entry;
1122 int unlocked = 0;
1123 int error = 0;
1124
1125 lck_rw_lock_shared(&sock_filter_lock);
1126 for (entry = so->so_filt; entry && error == 0;
1127 entry = entry->sfe_next_onsocket) {
1128 if ((entry->sfe_flags & SFEF_ATTACHED) &&
1129 entry->sfe_filter->sf_filter.sf_getoption) {
1130 /*
1131 * Retain the filter entry and release
1132 * the socket filter lock
1133 */
1134 sflt_entry_retain(entry);
1135 lck_rw_unlock_shared(&sock_filter_lock);
1136
1137 /* If the socket isn't already unlocked, unlock it */
1138 if (unlocked == 0) {
1139 socket_unlock(so, 0);
1140 unlocked = 1;
1141 }
1142
1143 /* Call the filter */
1144 error = entry->sfe_filter->sf_filter.sf_getoption(
1145 entry->sfe_cookie, so, sopt);
1146
1147 /*
1148 * Take the socket filter lock again
1149 * and release the entry
1150 */
1151 lck_rw_lock_shared(&sock_filter_lock);
1152 sflt_entry_release(entry);
1153 }
1154 }
1155 lck_rw_unlock_shared(&sock_filter_lock);
1156
1157 if (unlocked) {
1158 socket_lock(so, 0);
1159 }
1160
1161 return error;
1162 }
1163
1164 __private_extern__ int
sflt_data_out(struct socket * so,const struct sockaddr * to,mbuf_t * data,mbuf_t * control,sflt_data_flag_t flags)1165 sflt_data_out(struct socket *so, const struct sockaddr *to, mbuf_t *data,
1166 mbuf_t *control, sflt_data_flag_t flags)
1167 {
1168 if (so->so_filt == NULL || sflt_permission_check(sotoinpcb(so))) {
1169 return 0;
1170 }
1171
1172 /* Socket-options are checked at the MPTCP-layer */
1173 if (so->so_flags & SOF_MP_SUBFLOW) {
1174 return 0;
1175 }
1176
1177 struct socket_filter_entry *__single entry;
1178 int unlocked = 0;
1179 int setsendthread = 0;
1180 int error = 0;
1181
1182 lck_rw_lock_shared(&sock_filter_lock);
1183 for (entry = so->so_filt; entry && error == 0;
1184 entry = entry->sfe_next_onsocket) {
1185 if ((entry->sfe_flags & SFEF_ATTACHED) &&
1186 entry->sfe_filter->sf_filter.sf_data_out) {
1187 /*
1188 * Retain the filter entry and
1189 * release the socket filter lock
1190 */
1191 sflt_entry_retain(entry);
1192 lck_rw_unlock_shared(&sock_filter_lock);
1193
1194 /* If the socket isn't already unlocked, unlock it */
1195 if (unlocked == 0) {
1196 if (so->so_send_filt_thread == NULL) {
1197 setsendthread = 1;
1198 so->so_send_filt_thread =
1199 current_thread();
1200 }
1201 socket_unlock(so, 0);
1202 unlocked = 1;
1203 }
1204
1205 /* Call the filter */
1206 error = entry->sfe_filter->sf_filter.sf_data_out(
1207 entry->sfe_cookie, so, to, data, control, flags);
1208
1209 /*
1210 * Take the socket filter lock again
1211 * and release the entry
1212 */
1213 lck_rw_lock_shared(&sock_filter_lock);
1214 sflt_entry_release(entry);
1215 }
1216 }
1217 lck_rw_unlock_shared(&sock_filter_lock);
1218
1219 if (unlocked) {
1220 socket_lock(so, 0);
1221 if (setsendthread) {
1222 so->so_send_filt_thread = NULL;
1223 }
1224 }
1225
1226 return error;
1227 }
1228
1229 __private_extern__ int
sflt_data_in(struct socket * so,const struct sockaddr * from,mbuf_t * data,mbuf_t * control,sflt_data_flag_t flags)1230 sflt_data_in(struct socket *so, const struct sockaddr *from, mbuf_t *data,
1231 mbuf_t *control, sflt_data_flag_t flags)
1232 {
1233 if (so->so_filt == NULL || sflt_permission_check(sotoinpcb(so))) {
1234 return 0;
1235 }
1236
1237 /* Socket-options are checked at the MPTCP-layer */
1238 if (so->so_flags & SOF_MP_SUBFLOW) {
1239 return 0;
1240 }
1241
1242 struct socket_filter_entry *__single entry;
1243 int error = 0;
1244 int unlocked = 0;
1245
1246 lck_rw_lock_shared(&sock_filter_lock);
1247
1248 for (entry = so->so_filt; entry && (error == 0);
1249 entry = entry->sfe_next_onsocket) {
1250 if ((entry->sfe_flags & SFEF_ATTACHED) &&
1251 entry->sfe_filter->sf_filter.sf_data_in) {
1252 /*
1253 * Retain the filter entry and
1254 * release the socket filter lock
1255 */
1256 sflt_entry_retain(entry);
1257 lck_rw_unlock_shared(&sock_filter_lock);
1258
1259 /* If the socket isn't already unlocked, unlock it */
1260 if (unlocked == 0) {
1261 unlocked = 1;
1262 socket_unlock(so, 0);
1263 }
1264
1265 /* Call the filter */
1266 error = entry->sfe_filter->sf_filter.sf_data_in(
1267 entry->sfe_cookie, so, from, data, control, flags);
1268
1269 /*
1270 * Take the socket filter lock again
1271 * and release the entry
1272 */
1273 lck_rw_lock_shared(&sock_filter_lock);
1274 sflt_entry_release(entry);
1275 }
1276 }
1277 lck_rw_unlock_shared(&sock_filter_lock);
1278
1279 if (unlocked) {
1280 socket_lock(so, 0);
1281 }
1282
1283 return error;
1284 }
1285
1286 #pragma mark -- KPI --
1287
1288 errno_t
sflt_attach(socket_t socket,sflt_handle handle)1289 sflt_attach(socket_t socket, sflt_handle handle)
1290 {
1291 socket_lock(socket, 1);
1292 errno_t result = sflt_attach_internal(socket, handle);
1293 socket_unlock(socket, 1);
1294 return result;
1295 }
1296
1297 errno_t
sflt_detach(socket_t socket,sflt_handle handle)1298 sflt_detach(socket_t socket, sflt_handle handle)
1299 {
1300 struct socket_filter_entry *__single entry;
1301 errno_t result = 0;
1302
1303 if (socket == NULL || handle == 0) {
1304 return EINVAL;
1305 }
1306
1307 lck_rw_lock_exclusive(&sock_filter_lock);
1308 for (entry = socket->so_filt; entry; entry = entry->sfe_next_onsocket) {
1309 if (entry->sfe_filter->sf_filter.sf_handle == handle &&
1310 (entry->sfe_flags & SFEF_ATTACHED) != 0) {
1311 break;
1312 }
1313 }
1314
1315 if (entry != NULL) {
1316 sflt_detach_locked(entry);
1317 }
1318 lck_rw_unlock_exclusive(&sock_filter_lock);
1319
1320 return result;
1321 }
1322
1323 struct solist {
1324 struct solist *next;
1325 struct socket *so;
1326 };
1327
1328 static errno_t
sflt_register_common(const struct sflt_filter * infilter,int domain,int type,int protocol,bool is_internal)1329 sflt_register_common(const struct sflt_filter *infilter, int domain, int type,
1330 int protocol, bool is_internal)
1331 {
1332 const struct sflt_filter *filter = (const struct sflt_filter *__indexable)infilter;
1333 struct socket_filter *__single sock_filt = NULL;
1334 struct socket_filter *__single match = NULL;
1335 int error = 0;
1336 struct protosw *__single pr;
1337 unsigned int len;
1338 struct socket *__single so;
1339 struct inpcb *__single inp;
1340 struct solist *__single solisthead = NULL, *__single solist = NULL;
1341
1342 if ((domain != PF_INET) && (domain != PF_INET6)) {
1343 return ENOTSUP;
1344 }
1345
1346 pr = pffindproto(domain, protocol, type);
1347 if (pr == NULL) {
1348 return ENOENT;
1349 }
1350
1351 if (filter->sf_attach == NULL || filter->sf_detach == NULL ||
1352 filter->sf_handle == 0 || filter->sf_name == NULL) {
1353 return EINVAL;
1354 }
1355
1356 /* Allocate the socket filter */
1357 sock_filt = kalloc_type(struct socket_filter,
1358 Z_WAITOK | Z_ZERO | Z_NOFAIL);
1359
1360 /* Legacy sflt_filter length; current structure minus extended */
1361 len = sizeof(*filter) - sizeof(struct sflt_filter_ext);
1362 /*
1363 * Include extended fields if filter defines SFLT_EXTENDED.
1364 * We've zeroed out our internal sflt_filter placeholder,
1365 * so any unused portion would have been taken care of.
1366 */
1367 if (filter->sf_flags & SFLT_EXTENDED) {
1368 unsigned int ext_len = filter->sf_len;
1369
1370 if (ext_len > sizeof(struct sflt_filter_ext)) {
1371 ext_len = sizeof(struct sflt_filter_ext);
1372 }
1373
1374 len += ext_len;
1375 }
1376 bcopy(filter, &sock_filt->sf_filter, len);
1377
1378 lck_rw_lock_exclusive(&sock_filter_lock);
1379 /* Look for an existing entry */
1380 TAILQ_FOREACH(match, &sock_filter_head, sf_global_next) {
1381 if (match->sf_filter.sf_handle ==
1382 sock_filt->sf_filter.sf_handle) {
1383 break;
1384 }
1385 }
1386
1387 /* Add the entry only if there was no existing entry */
1388 if (match == NULL) {
1389 TAILQ_INSERT_TAIL(&sock_filter_head, sock_filt, sf_global_next);
1390 if ((sock_filt->sf_filter.sf_flags & SFLT_GLOBAL) != 0) {
1391 TAILQ_INSERT_TAIL(&pr->pr_filter_head, sock_filt,
1392 sf_protosw_next);
1393 sock_filt->sf_proto = pr;
1394 }
1395 os_ref_init(&sock_filt->sf_refcount, NULL);
1396
1397 OSIncrementAtomic64(&net_api_stats.nas_sfltr_register_count);
1398 INC_ATOMIC_INT64_LIM(net_api_stats.nas_sfltr_register_total);
1399 if (is_internal) {
1400 sock_filt->sf_flags |= SFF_INTERNAL;
1401 OSIncrementAtomic64(&net_api_stats.nas_sfltr_register_os_count);
1402 INC_ATOMIC_INT64_LIM(net_api_stats.nas_sfltr_register_os_total);
1403 }
1404 }
1405 #if SKYWALK
1406 if (kernel_is_macos_or_server()) {
1407 net_filter_event_mark(NET_FILTER_EVENT_SOCKET,
1408 net_check_compatible_sfltr());
1409 net_filter_event_mark(NET_FILTER_EVENT_ALF,
1410 net_check_compatible_alf());
1411 net_filter_event_mark(NET_FILTER_EVENT_PARENTAL_CONTROLS,
1412 net_check_compatible_parental_controls());
1413 }
1414 #endif /* SKYWALK */
1415
1416 lck_rw_unlock_exclusive(&sock_filter_lock);
1417
1418 if (match != NULL) {
1419 kfree_type(struct socket_filter, sock_filt);
1420 return EEXIST;
1421 }
1422
1423 if (!(filter->sf_flags & SFLT_EXTENDED_REGISTRY)) {
1424 return error;
1425 }
1426
1427 /*
1428 * Setup the filter on the TCP and UDP sockets already created.
1429 */
1430 #define SOLIST_ADD(_so) do { \
1431 solist->next = solisthead; \
1432 sock_retain((_so)); \
1433 solist->so = (_so); \
1434 solisthead = solist; \
1435 } while (0)
1436 if (protocol == IPPROTO_TCP) {
1437 lck_rw_lock_shared(&tcbinfo.ipi_lock);
1438 LIST_FOREACH(inp, tcbinfo.ipi_listhead, inp_list) {
1439 so = inp->inp_socket;
1440 if (so == NULL || (so->so_state & SS_DEFUNCT) ||
1441 (!(so->so_flags & SOF_MP_SUBFLOW) &&
1442 (so->so_state & SS_NOFDREF)) ||
1443 !SOCK_CHECK_DOM(so, domain) ||
1444 !SOCK_CHECK_TYPE(so, type)) {
1445 continue;
1446 }
1447 solist = kalloc_type(struct solist, Z_NOWAIT);
1448 if (!solist) {
1449 continue;
1450 }
1451 SOLIST_ADD(so);
1452 }
1453 lck_rw_done(&tcbinfo.ipi_lock);
1454 } else if (protocol == IPPROTO_UDP) {
1455 lck_rw_lock_shared(&udbinfo.ipi_lock);
1456 LIST_FOREACH(inp, udbinfo.ipi_listhead, inp_list) {
1457 so = inp->inp_socket;
1458 if (so == NULL || (so->so_state & SS_DEFUNCT) ||
1459 (!(so->so_flags & SOF_MP_SUBFLOW) &&
1460 (so->so_state & SS_NOFDREF)) ||
1461 !SOCK_CHECK_DOM(so, domain) ||
1462 !SOCK_CHECK_TYPE(so, type)) {
1463 continue;
1464 }
1465 solist = kalloc_type(struct solist, Z_NOWAIT);
1466 if (!solist) {
1467 continue;
1468 }
1469 SOLIST_ADD(so);
1470 }
1471 lck_rw_done(&udbinfo.ipi_lock);
1472 }
1473 /* XXX it's possible to walk the raw socket list as well */
1474 #undef SOLIST_ADD
1475
1476 while (solisthead) {
1477 sflt_handle handle = filter->sf_handle;
1478
1479 so = solisthead->so;
1480 socket_lock(so, 0);
1481 sflt_initsock(so);
1482 if (so->so_state & SS_ISCONNECTING) {
1483 sflt_notify_after_register(so, sock_evt_connecting,
1484 handle);
1485 } else if (so->so_state & SS_ISCONNECTED) {
1486 sflt_notify_after_register(so, sock_evt_connected,
1487 handle);
1488 } else if ((so->so_state &
1489 (SS_ISDISCONNECTING | SS_CANTRCVMORE | SS_CANTSENDMORE)) ==
1490 (SS_ISDISCONNECTING | SS_CANTRCVMORE | SS_CANTSENDMORE)) {
1491 sflt_notify_after_register(so, sock_evt_disconnecting,
1492 handle);
1493 } else if ((so->so_state &
1494 (SS_CANTRCVMORE | SS_CANTSENDMORE | SS_ISDISCONNECTED)) ==
1495 (SS_CANTRCVMORE | SS_CANTSENDMORE | SS_ISDISCONNECTED)) {
1496 sflt_notify_after_register(so, sock_evt_disconnected,
1497 handle);
1498 } else if (so->so_state & SS_CANTSENDMORE) {
1499 sflt_notify_after_register(so, sock_evt_cantsendmore,
1500 handle);
1501 } else if (so->so_state & SS_CANTRCVMORE) {
1502 sflt_notify_after_register(so, sock_evt_cantrecvmore,
1503 handle);
1504 }
1505 socket_unlock(so, 0);
1506 /* XXX no easy way to post the sock_evt_closing event */
1507 sock_release(so);
1508 solist = solisthead;
1509 solisthead = solisthead->next;
1510 kfree_type(struct solist, solist);
1511 }
1512
1513 return error;
1514 }
1515
1516 errno_t
sflt_register_internal(const struct sflt_filter * filter,int domain,int type,int protocol)1517 sflt_register_internal(const struct sflt_filter *filter, int domain, int type,
1518 int protocol)
1519 {
1520 return sflt_register_common(filter, domain, type, protocol, true);
1521 }
1522
1523 #define MAX_NUM_FRAMES 5
1524
1525 errno_t
sflt_register(const struct sflt_filter * filter,int domain,int type,int protocol)1526 sflt_register(const struct sflt_filter *filter, int domain, int type,
1527 int protocol)
1528 {
1529 return sflt_register_common(filter, domain, type, protocol, false);
1530 }
1531
1532 errno_t
sflt_unregister(sflt_handle handle)1533 sflt_unregister(sflt_handle handle)
1534 {
1535 struct socket_filter *__single filter;
1536 lck_rw_lock_exclusive(&sock_filter_lock);
1537
1538 /* Find the entry by the handle */
1539 TAILQ_FOREACH(filter, &sock_filter_head, sf_global_next) {
1540 if (filter->sf_filter.sf_handle == handle) {
1541 break;
1542 }
1543 }
1544
1545 if (filter) {
1546 if (filter->sf_flags & SFF_INTERNAL) {
1547 VERIFY(OSDecrementAtomic64(&net_api_stats.nas_sfltr_register_os_count) > 0);
1548 }
1549 VERIFY(OSDecrementAtomic64(&net_api_stats.nas_sfltr_register_count) > 0);
1550
1551 /* Remove it from the global list */
1552 TAILQ_REMOVE(&sock_filter_head, filter, sf_global_next);
1553
1554 /* Remove it from the protosw list */
1555 if ((filter->sf_filter.sf_flags & SFLT_GLOBAL) != 0) {
1556 TAILQ_REMOVE(&filter->sf_proto->pr_filter_head,
1557 filter, sf_protosw_next);
1558 }
1559
1560 /* Detach from any sockets */
1561 struct socket_filter_entry *__single entry = NULL;
1562
1563 for (entry = filter->sf_entry_head; entry;
1564 entry = entry->sfe_next_onfilter) {
1565 sflt_detach_locked(entry);
1566 }
1567
1568 /* Release the filter */
1569 sflt_release_locked(filter);
1570 }
1571 #if SKYWALK
1572 if (kernel_is_macos_or_server()) {
1573 net_filter_event_mark(NET_FILTER_EVENT_SOCKET,
1574 net_check_compatible_sfltr());
1575 net_filter_event_mark(NET_FILTER_EVENT_ALF,
1576 net_check_compatible_alf());
1577 net_filter_event_mark(NET_FILTER_EVENT_PARENTAL_CONTROLS,
1578 net_check_compatible_parental_controls());
1579 }
1580 #endif /* SKYWALK */
1581
1582 lck_rw_unlock_exclusive(&sock_filter_lock);
1583
1584 if (filter == NULL) {
1585 return ENOENT;
1586 }
1587
1588 return 0;
1589 }
1590
1591 errno_t
sock_inject_data_in(socket_t so,const struct sockaddr * from,mbuf_t data,mbuf_t control,sflt_data_flag_t flags)1592 sock_inject_data_in(socket_t so, const struct sockaddr *from, mbuf_t data,
1593 mbuf_t control, sflt_data_flag_t flags)
1594 {
1595 int error = 0;
1596
1597 if (so == NULL || data == NULL) {
1598 return EINVAL;
1599 }
1600
1601 if (flags & sock_data_filt_flag_oob) {
1602 return ENOTSUP;
1603 }
1604
1605 socket_lock(so, 1);
1606
1607 /* reject if this is a subflow socket */
1608 if (so->so_flags & SOF_MP_SUBFLOW) {
1609 error = ENOTSUP;
1610 goto done;
1611 }
1612
1613 if (from) {
1614 if (sbappendaddr(&so->so_rcv,
1615 __DECONST_SA(from), data, control, NULL)) {
1616 sorwakeup(so);
1617 }
1618 goto done;
1619 }
1620
1621 if (control) {
1622 if (sbappendcontrol(&so->so_rcv, data, control, NULL)) {
1623 sorwakeup(so);
1624 }
1625 goto done;
1626 }
1627
1628 if (flags & sock_data_filt_flag_record) {
1629 if (control || from) {
1630 error = EINVAL;
1631 goto done;
1632 }
1633 if (sbappendrecord(&so->so_rcv, (struct mbuf *)data)) {
1634 sorwakeup(so);
1635 }
1636 goto done;
1637 }
1638
1639 if (sbappend(&so->so_rcv, data)) {
1640 sorwakeup(so);
1641 }
1642 done:
1643 socket_unlock(so, 1);
1644 return error;
1645 }
1646
1647 errno_t
sock_inject_data_out(socket_t so,const struct sockaddr * to,mbuf_t data,mbuf_t control,sflt_data_flag_t flags)1648 sock_inject_data_out(socket_t so, const struct sockaddr *to, mbuf_t data,
1649 mbuf_t control, sflt_data_flag_t flags)
1650 {
1651 int sosendflags = 0;
1652 int error = 0;
1653
1654 /* reject if this is a subflow socket */
1655 if (so->so_flags & SOF_MP_SUBFLOW) {
1656 return ENOTSUP;
1657 }
1658
1659 if (flags & sock_data_filt_flag_oob) {
1660 sosendflags = MSG_OOB;
1661 }
1662
1663 #if SKYWALK
1664 sk_protect_t protect = sk_async_transmit_protect();
1665 #endif /* SKYWALK */
1666
1667 error = sosend(so, __DECONST_SA(to), NULL,
1668 data, control, sosendflags);
1669
1670 #if SKYWALK
1671 sk_async_transmit_unprotect(protect);
1672 #endif /* SKYWALK */
1673
1674 return error;
1675 }
1676
1677 sockopt_dir
sockopt_direction(sockopt_t sopt)1678 sockopt_direction(sockopt_t sopt)
1679 {
1680 return (sopt->sopt_dir == SOPT_GET) ? sockopt_get : sockopt_set;
1681 }
1682
1683 int
sockopt_level(sockopt_t sopt)1684 sockopt_level(sockopt_t sopt)
1685 {
1686 return sopt->sopt_level;
1687 }
1688
1689 int
sockopt_name(sockopt_t sopt)1690 sockopt_name(sockopt_t sopt)
1691 {
1692 return sopt->sopt_name;
1693 }
1694
1695 size_t
sockopt_valsize(sockopt_t sopt)1696 sockopt_valsize(sockopt_t sopt)
1697 {
1698 return sopt->sopt_valsize;
1699 }
1700
1701 errno_t
sockopt_copyin(sockopt_t sopt,void * __sized_by (len)data,size_t len)1702 sockopt_copyin(sockopt_t sopt, void *__sized_by(len) data, size_t len)
1703 {
1704 return sooptcopyin(sopt, data, len, len);
1705 }
1706
1707 errno_t
sockopt_copyout(sockopt_t sopt,void * __sized_by (len)data,size_t len)1708 sockopt_copyout(sockopt_t sopt, void *__sized_by(len) data, size_t len)
1709 {
1710 return sooptcopyout(sopt, data, len);
1711 }
1712
1713 #if SKYWALK
1714 static bool
net_check_compatible_sfltr(void)1715 net_check_compatible_sfltr(void)
1716 {
1717 if (net_api_stats.nas_sfltr_register_count > net_api_stats.nas_sfltr_register_os_count) {
1718 return false;
1719 }
1720 return true;
1721 }
1722
1723 bool
net_check_compatible_alf(void)1724 net_check_compatible_alf(void)
1725 {
1726 int alf_perm;
1727 size_t len = sizeof(alf_perm);
1728 errno_t error;
1729
1730 error = kernel_sysctlbyname("net.alf.perm", &alf_perm, &len, NULL, 0);
1731 if (error == 0) {
1732 if (alf_perm != 0) {
1733 return false;
1734 }
1735 }
1736 return true;
1737 }
1738
1739 static bool
net_check_compatible_parental_controls(void)1740 net_check_compatible_parental_controls(void)
1741 {
1742 /*
1743 * Assumes the first 4 OS socket filters are for ALF and additional
1744 * OS filters are for Parental Controls web content filter
1745 */
1746 if (net_api_stats.nas_sfltr_register_os_count > 4) {
1747 return false;
1748 }
1749 return true;
1750 }
1751 #endif /* SKYWALK */
1752