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