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