xref: /xnu-12377.41.6/bsd/kern/kpi_socketfilter.c (revision bbb1b6f9e71b8cdde6e5cd6f4841f207dee3d828)
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