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