xref: /xnu-10002.81.5/bsd/kern/kern_control.c (revision 5e3eaea39dcf651e66cb99ba7d70e32cc4a99587)
1 /*
2  * Copyright (c) 1999-2022 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 /*
30  * Kernel Control domain - allows control connections to
31  *  and to read/write data.
32  *
33  * Vincent Lubet, 040506
34  * Christophe Allie, 010928
35  * Justin C. Walker, 990319
36  */
37 
38 #include <sys/types.h>
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/syslog.h>
42 #include <sys/socket.h>
43 #include <sys/socketvar.h>
44 #include <sys/protosw.h>
45 #include <sys/domain.h>
46 #include <sys/malloc.h>
47 #include <sys/mbuf.h>
48 #include <sys/sys_domain.h>
49 #include <sys/kern_event.h>
50 #include <sys/kern_control.h>
51 #include <sys/kauth.h>
52 #include <sys/sysctl.h>
53 #include <sys/proc_info.h>
54 #include <net/if_var.h>
55 
56 #include <mach/vm_types.h>
57 
58 #include <kern/thread.h>
59 
60 struct kctl {
61 	TAILQ_ENTRY(kctl)       next;           /* controller chain */
62 	kern_ctl_ref            kctlref;
63 
64 	/* controller information provided when registering */
65 	char                    name[MAX_KCTL_NAME];    /* unique identifier */
66 	u_int32_t               id;
67 	u_int32_t               reg_unit;
68 
69 	/* misc communication information */
70 	u_int32_t               flags;          /* support flags */
71 	u_int32_t               recvbufsize;    /* request more than the default buffer size */
72 	u_int32_t               sendbufsize;    /* request more than the default buffer size */
73 
74 	/* Dispatch functions */
75 	ctl_setup_func          setup;          /* Setup contact */
76 	ctl_bind_func           bind;           /* Prepare contact */
77 	ctl_connect_func        connect;        /* Make contact */
78 	ctl_disconnect_func     disconnect;     /* Break contact */
79 	ctl_send_func           send;           /* Send data to nke */
80 	ctl_send_list_func      send_list;      /* Send list of packets */
81 	ctl_setopt_func         setopt;         /* set kctl configuration */
82 	ctl_getopt_func         getopt;         /* get kctl configuration */
83 	ctl_rcvd_func           rcvd;           /* Notify nke when client reads data */
84 
85 	TAILQ_HEAD(, ctl_cb)    kcb_head;
86 	u_int32_t               lastunit;
87 };
88 
89 #if DEVELOPMENT || DEBUG
90 enum ctl_status {
91 	KCTL_DISCONNECTED = 0,
92 	KCTL_CONNECTING = 1,
93 	KCTL_CONNECTED = 2
94 };
95 #endif /* DEVELOPMENT || DEBUG */
96 
97 struct ctl_cb {
98 	TAILQ_ENTRY(ctl_cb)     next;           /* controller chain */
99 	lck_mtx_t               mtx;
100 	struct socket           *so;            /* controlling socket */
101 	struct kctl             *kctl;          /* back pointer to controller */
102 	void                    *userdata;
103 	struct sockaddr_ctl     sac;
104 	uint32_t                usecount;
105 	uint32_t                kcb_usecount;
106 	uint32_t                require_clearing_count;
107 #if DEVELOPMENT || DEBUG
108 	enum ctl_status         status;
109 #endif /* DEVELOPMENT || DEBUG */
110 };
111 
112 #ifndef ROUNDUP64
113 #define ROUNDUP64(x) P2ROUNDUP((x), sizeof (u_int64_t))
114 #endif
115 
116 #ifndef ADVANCE64
117 #define ADVANCE64(p, n) (void*)((char *)(p) + ROUNDUP64(n))
118 #endif
119 
120 /*
121  * Definitions and vars for we support
122  */
123 
124 #define CTL_SENDSIZE    (2 * 1024)      /* default buffer size */
125 #define CTL_RECVSIZE    (8 * 1024)      /* default buffer size */
126 
127 /*
128  * Definitions and vars for we support
129  */
130 
131 const u_int32_t         ctl_maxunit = 65536;
132 static LCK_ATTR_DECLARE(ctl_lck_attr, 0, 0);
133 static LCK_GRP_DECLARE(ctl_lck_grp, "Kernel Control Protocol");
134 static LCK_MTX_DECLARE_ATTR(ctl_mtx, &ctl_lck_grp, &ctl_lck_attr);
135 
136 /* all the controllers are chained */
137 TAILQ_HEAD(kctl_list, kctl) ctl_head = TAILQ_HEAD_INITIALIZER(ctl_head);
138 
139 static int ctl_attach(struct socket *, int, struct proc *);
140 static int ctl_detach(struct socket *);
141 static int ctl_sofreelastref(struct socket *so);
142 static int ctl_bind(struct socket *, struct sockaddr *, struct proc *);
143 static int ctl_connect(struct socket *, struct sockaddr *, struct proc *);
144 static int ctl_disconnect(struct socket *);
145 static int ctl_ioctl(struct socket *so, u_long cmd, caddr_t data,
146     struct ifnet *ifp, struct proc *p);
147 static int ctl_send(struct socket *, int, struct mbuf *,
148     struct sockaddr *, struct mbuf *, struct proc *);
149 static int ctl_send_list(struct socket *, struct mbuf *, u_int *, int);
150 static int ctl_ctloutput(struct socket *, struct sockopt *);
151 static int ctl_peeraddr(struct socket *so, struct sockaddr **nam);
152 static int ctl_usr_rcvd(struct socket *so, int flags);
153 
154 static struct kctl *ctl_find_by_name(const char *);
155 static struct kctl *ctl_find_by_id_unit(u_int32_t id, u_int32_t unit);
156 
157 static struct socket *kcb_find_socket(kern_ctl_ref kctlref, u_int32_t unit,
158     u_int32_t *);
159 static struct ctl_cb *kcb_find(struct kctl *, u_int32_t unit);
160 static void ctl_post_msg(u_int32_t event_code, u_int32_t id);
161 
162 static int ctl_lock(struct socket *, int, void *);
163 static int ctl_unlock(struct socket *, int, void *);
164 static lck_mtx_t * ctl_getlock(struct socket *, int);
165 
166 static struct pr_usrreqs ctl_usrreqs = {
167 	.pru_attach =           ctl_attach,
168 	.pru_bind =             ctl_bind,
169 	.pru_connect =          ctl_connect,
170 	.pru_control =          ctl_ioctl,
171 	.pru_detach =           ctl_detach,
172 	.pru_disconnect =       ctl_disconnect,
173 	.pru_peeraddr =         ctl_peeraddr,
174 	.pru_rcvd =             ctl_usr_rcvd,
175 	.pru_send =             ctl_send,
176 	.pru_send_list =        ctl_send_list,
177 	.pru_sosend =           sosend,
178 	.pru_sosend_list =      sosend_list,
179 	.pru_soreceive =        soreceive,
180 };
181 
182 static struct protosw kctlsw[] = {
183 	{
184 		.pr_type =      SOCK_DGRAM,
185 		.pr_protocol =  SYSPROTO_CONTROL,
186 		.pr_flags =     PR_ATOMIC | PR_CONNREQUIRED | PR_PCBLOCK | PR_WANTRCVD,
187 		.pr_ctloutput = ctl_ctloutput,
188 		.pr_usrreqs =   &ctl_usrreqs,
189 		.pr_lock =      ctl_lock,
190 		.pr_unlock =    ctl_unlock,
191 		.pr_getlock =   ctl_getlock,
192 	},
193 	{
194 		.pr_type =      SOCK_STREAM,
195 		.pr_protocol =  SYSPROTO_CONTROL,
196 		.pr_flags =     PR_CONNREQUIRED | PR_PCBLOCK | PR_WANTRCVD,
197 		.pr_ctloutput = ctl_ctloutput,
198 		.pr_usrreqs =   &ctl_usrreqs,
199 		.pr_lock =      ctl_lock,
200 		.pr_unlock =    ctl_unlock,
201 		.pr_getlock =   ctl_getlock,
202 	}
203 };
204 
205 __private_extern__ int kctl_reg_list SYSCTL_HANDLER_ARGS;
206 __private_extern__ int kctl_pcblist SYSCTL_HANDLER_ARGS;
207 __private_extern__ int kctl_getstat SYSCTL_HANDLER_ARGS;
208 
209 
210 SYSCTL_NODE(_net_systm, OID_AUTO, kctl,
211     CTLFLAG_RW | CTLFLAG_LOCKED, 0, "Kernel control family");
212 
213 struct kctlstat kctlstat;
214 SYSCTL_PROC(_net_systm_kctl, OID_AUTO, stats,
215     CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0,
216     kctl_getstat, "S,kctlstat", "");
217 
218 SYSCTL_PROC(_net_systm_kctl, OID_AUTO, reg_list,
219     CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0,
220     kctl_reg_list, "S,xkctl_reg", "");
221 
222 SYSCTL_PROC(_net_systm_kctl, OID_AUTO, pcblist,
223     CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, 0, 0,
224     kctl_pcblist, "S,xkctlpcb", "");
225 
226 u_int32_t ctl_autorcvbuf_max = 256 * 1024;
227 SYSCTL_INT(_net_systm_kctl, OID_AUTO, autorcvbufmax,
228     CTLFLAG_RW | CTLFLAG_LOCKED, &ctl_autorcvbuf_max, 0, "");
229 
230 u_int32_t ctl_autorcvbuf_high = 0;
231 SYSCTL_INT(_net_systm_kctl, OID_AUTO, autorcvbufhigh,
232     CTLFLAG_RD | CTLFLAG_LOCKED, &ctl_autorcvbuf_high, 0, "");
233 
234 u_int32_t ctl_debug = 0;
235 SYSCTL_INT(_net_systm_kctl, OID_AUTO, debug,
236     CTLFLAG_RW | CTLFLAG_LOCKED, &ctl_debug, 0, "");
237 
238 #if DEVELOPMENT || DEBUG
239 u_int32_t ctl_panic_debug = 0;
240 SYSCTL_INT(_net_systm_kctl, OID_AUTO, panicdebug,
241     CTLFLAG_RW | CTLFLAG_LOCKED, &ctl_panic_debug, 0, "");
242 #endif /* DEVELOPMENT || DEBUG */
243 
244 #define KCTL_TBL_INC 16
245 
246 static uintptr_t kctl_tbl_size = 0;
247 static u_int32_t kctl_tbl_growing = 0;
248 static u_int32_t kctl_tbl_growing_waiting = 0;
249 static uintptr_t kctl_tbl_count = 0;
250 static struct kctl **kctl_table = NULL;
251 static uintptr_t kctl_ref_gencnt = 0;
252 
253 static void kctl_tbl_grow(void);
254 static kern_ctl_ref kctl_make_ref(struct kctl *kctl);
255 static void kctl_delete_ref(kern_ctl_ref);
256 static struct kctl *kctl_from_ref(kern_ctl_ref);
257 
258 /*
259  * Install the protosw's for the Kernel Control manager.
260  */
261 __private_extern__ void
kern_control_init(struct domain * dp)262 kern_control_init(struct domain *dp)
263 {
264 	struct protosw *pr;
265 	int i;
266 	int kctl_proto_count = (sizeof(kctlsw) / sizeof(struct protosw));
267 
268 	VERIFY(!(dp->dom_flags & DOM_INITIALIZED));
269 	VERIFY(dp == systemdomain);
270 
271 	for (i = 0, pr = &kctlsw[0]; i < kctl_proto_count; i++, pr++) {
272 		net_add_proto(pr, dp, 1);
273 	}
274 }
275 
276 static void
kcb_delete(struct ctl_cb * kcb)277 kcb_delete(struct ctl_cb *kcb)
278 {
279 	if (kcb != 0) {
280 		lck_mtx_destroy(&kcb->mtx, &ctl_lck_grp);
281 		kfree_type(struct ctl_cb, kcb);
282 	}
283 }
284 
285 /*
286  * Kernel Controller user-request functions
287  * attach function must exist and succeed
288  * detach not necessary
289  * we need a pcb for the per socket mutex
290  */
291 static int
ctl_attach(struct socket * so,int proto,struct proc * p)292 ctl_attach(struct socket *so, int proto, struct proc *p)
293 {
294 #pragma unused(proto, p)
295 	struct ctl_cb *kcb = 0;
296 
297 	kcb = kalloc_type(struct ctl_cb, Z_WAITOK | Z_ZERO | Z_NOFAIL);
298 
299 	lck_mtx_init(&kcb->mtx, &ctl_lck_grp, &ctl_lck_attr);
300 	kcb->so = so;
301 	so->so_pcb = (caddr_t)kcb;
302 
303 	/*
304 	 * For datagram, use character count for sbspace as its value
305 	 * may be use for packetization and we do not want to
306 	 * drop packets based on the sbspace hint that was just provided
307 	 */
308 	if (so->so_proto->pr_type == SOCK_DGRAM) {
309 		so->so_rcv.sb_flags |= SB_KCTL;
310 		so->so_snd.sb_flags |= SB_KCTL;
311 	}
312 	return 0;
313 }
314 
315 static int
ctl_sofreelastref(struct socket * so)316 ctl_sofreelastref(struct socket *so)
317 {
318 	struct ctl_cb   *kcb = (struct ctl_cb *)so->so_pcb;
319 
320 	so->so_pcb = 0;
321 
322 	if (kcb != 0) {
323 		struct kctl             *kctl;
324 		if ((kctl = kcb->kctl) != 0) {
325 			lck_mtx_lock(&ctl_mtx);
326 			TAILQ_REMOVE(&kctl->kcb_head, kcb, next);
327 			kctlstat.kcs_pcbcount--;
328 			kctlstat.kcs_gencnt++;
329 			lck_mtx_unlock(&ctl_mtx);
330 		}
331 		kcb_delete(kcb);
332 	}
333 	sofreelastref(so, 1);
334 	return 0;
335 }
336 
337 /*
338  * Use this function and ctl_kcb_require_clearing to serialize
339  * critical calls into the kctl subsystem
340  */
341 static void
ctl_kcb_increment_use_count(struct ctl_cb * kcb,lck_mtx_t * mutex_held)342 ctl_kcb_increment_use_count(struct ctl_cb *kcb, lck_mtx_t *mutex_held)
343 {
344 	LCK_MTX_ASSERT(mutex_held, LCK_MTX_ASSERT_OWNED);
345 	while (kcb->require_clearing_count > 0) {
346 		msleep(&kcb->require_clearing_count, mutex_held, PSOCK | PCATCH, "kcb_require_clearing", NULL);
347 	}
348 	kcb->kcb_usecount++;
349 }
350 
351 static void
ctl_kcb_require_clearing(struct ctl_cb * kcb,lck_mtx_t * mutex_held)352 ctl_kcb_require_clearing(struct ctl_cb *kcb, lck_mtx_t *mutex_held)
353 {
354 	assert(kcb->kcb_usecount != 0);
355 	kcb->require_clearing_count++;
356 	kcb->kcb_usecount--;
357 	while (kcb->kcb_usecount > 0) { // we need to wait until no one else is running
358 		msleep(&kcb->kcb_usecount, mutex_held, PSOCK | PCATCH, "kcb_usecount", NULL);
359 	}
360 	kcb->kcb_usecount++;
361 }
362 
363 static void
ctl_kcb_done_clearing(struct ctl_cb * kcb)364 ctl_kcb_done_clearing(struct ctl_cb *kcb)
365 {
366 	assert(kcb->require_clearing_count != 0);
367 	kcb->require_clearing_count--;
368 	wakeup((caddr_t)&kcb->require_clearing_count);
369 }
370 
371 static void
ctl_kcb_decrement_use_count(struct ctl_cb * kcb)372 ctl_kcb_decrement_use_count(struct ctl_cb *kcb)
373 {
374 	assert(kcb->kcb_usecount != 0);
375 	kcb->kcb_usecount--;
376 	if (kcb->require_clearing_count != 0) {
377 		wakeup((caddr_t)&kcb->kcb_usecount);
378 	}
379 }
380 
381 static int
ctl_detach(struct socket * so)382 ctl_detach(struct socket *so)
383 {
384 	struct ctl_cb   *kcb = (struct ctl_cb *)so->so_pcb;
385 
386 	if (kcb == 0) {
387 		return 0;
388 	}
389 
390 	lck_mtx_t *mtx_held = socket_getlock(so, PR_F_WILLUNLOCK);
391 	ctl_kcb_increment_use_count(kcb, mtx_held);
392 	ctl_kcb_require_clearing(kcb, mtx_held);
393 
394 	if (kcb->kctl != NULL && kcb->kctl->bind != NULL &&
395 	    kcb->userdata != NULL && !(so->so_state & SS_ISCONNECTED)) {
396 		// The unit was bound, but not connected
397 		// Invoke the disconnected call to cleanup
398 		if (kcb->kctl->disconnect != NULL) {
399 			socket_unlock(so, 0);
400 			(*kcb->kctl->disconnect)(kcb->kctl->kctlref,
401 			    kcb->sac.sc_unit, kcb->userdata);
402 			socket_lock(so, 0);
403 		}
404 	}
405 
406 	soisdisconnected(so);
407 #if DEVELOPMENT || DEBUG
408 	kcb->status = KCTL_DISCONNECTED;
409 #endif /* DEVELOPMENT || DEBUG */
410 	so->so_flags |= SOF_PCBCLEARING;
411 	ctl_kcb_done_clearing(kcb);
412 	ctl_kcb_decrement_use_count(kcb);
413 	return 0;
414 }
415 
416 static int
ctl_setup_kctl(struct socket * so,struct sockaddr * nam,struct proc * p)417 ctl_setup_kctl(struct socket *so, struct sockaddr *nam, struct proc *p)
418 {
419 	struct kctl *kctl = NULL;
420 	int error = 0;
421 	struct sockaddr_ctl     sa;
422 	struct ctl_cb *kcb = (struct ctl_cb *)so->so_pcb;
423 	struct ctl_cb *kcb_next = NULL;
424 	u_int32_t recvbufsize, sendbufsize;
425 
426 	if (kcb == 0) {
427 		panic("ctl_setup_kctl so_pcb null");
428 	}
429 
430 	if (kcb->kctl != NULL) {
431 		// Already set up, skip
432 		return 0;
433 	}
434 
435 	if (nam->sa_len != sizeof(struct sockaddr_ctl)) {
436 		return EINVAL;
437 	}
438 
439 	bcopy(nam, &sa, sizeof(struct sockaddr_ctl));
440 
441 	lck_mtx_lock(&ctl_mtx);
442 	kctl = ctl_find_by_id_unit(sa.sc_id, sa.sc_unit);
443 	if (kctl == NULL) {
444 		lck_mtx_unlock(&ctl_mtx);
445 		return ENOENT;
446 	}
447 
448 	if (((kctl->flags & CTL_FLAG_REG_SOCK_STREAM) &&
449 	    (so->so_type != SOCK_STREAM)) ||
450 	    (!(kctl->flags & CTL_FLAG_REG_SOCK_STREAM) &&
451 	    (so->so_type != SOCK_DGRAM))) {
452 		lck_mtx_unlock(&ctl_mtx);
453 		return EPROTOTYPE;
454 	}
455 
456 	if (kctl->flags & CTL_FLAG_PRIVILEGED) {
457 		if (p == 0) {
458 			lck_mtx_unlock(&ctl_mtx);
459 			return EINVAL;
460 		}
461 		if (kauth_cred_issuser(kauth_cred_get()) == 0) {
462 			lck_mtx_unlock(&ctl_mtx);
463 			return EPERM;
464 		}
465 	}
466 
467 	if (kctl->setup != NULL) {
468 		error = (*kctl->setup)(&sa.sc_unit, &kcb->userdata);
469 		if (error != 0) {
470 			lck_mtx_unlock(&ctl_mtx);
471 			return error;
472 		}
473 	} else if ((kctl->flags & CTL_FLAG_REG_ID_UNIT) || sa.sc_unit != 0) {
474 		if (kcb_find(kctl, sa.sc_unit) != NULL) {
475 			lck_mtx_unlock(&ctl_mtx);
476 			return EBUSY;
477 		}
478 	} else {
479 		/* Find an unused ID, assumes control IDs are in order */
480 		u_int32_t unit = 1;
481 
482 		TAILQ_FOREACH(kcb_next, &kctl->kcb_head, next) {
483 			if (kcb_next->sac.sc_unit > unit) {
484 				/* Found a gap, lets fill it in */
485 				break;
486 			}
487 			unit = kcb_next->sac.sc_unit + 1;
488 			if (unit == ctl_maxunit) {
489 				break;
490 			}
491 		}
492 
493 		if (unit == ctl_maxunit) {
494 			lck_mtx_unlock(&ctl_mtx);
495 			return EBUSY;
496 		}
497 
498 		sa.sc_unit = unit;
499 	}
500 
501 	bcopy(&sa, &kcb->sac, sizeof(struct sockaddr_ctl));
502 	kcb->kctl = kctl;
503 	if (kcb_next != NULL) {
504 		TAILQ_INSERT_BEFORE(kcb_next, kcb, next);
505 	} else {
506 		TAILQ_INSERT_TAIL(&kctl->kcb_head, kcb, next);
507 	}
508 	kctlstat.kcs_pcbcount++;
509 	kctlstat.kcs_gencnt++;
510 	kctlstat.kcs_connections++;
511 	lck_mtx_unlock(&ctl_mtx);
512 
513 	/*
514 	 * rdar://15526688: Limit the send and receive sizes to sb_max
515 	 * by using the same scaling as sbreserve()
516 	 */
517 	if (kctl->sendbufsize > sb_max_adj) {
518 		sendbufsize = (u_int32_t)sb_max_adj;
519 	} else {
520 		sendbufsize = kctl->sendbufsize;
521 	}
522 
523 	if (kctl->recvbufsize > sb_max_adj) {
524 		recvbufsize = (u_int32_t)sb_max_adj;
525 	} else {
526 		recvbufsize = kctl->recvbufsize;
527 	}
528 
529 	error = soreserve(so, sendbufsize, recvbufsize);
530 	if (error) {
531 		if (ctl_debug) {
532 			printf("%s - soreserve(%llx, %u, %u) error %d\n",
533 			    __func__, (uint64_t)VM_KERNEL_ADDRPERM(so),
534 			    sendbufsize, recvbufsize, error);
535 		}
536 		goto done;
537 	}
538 
539 done:
540 	if (error) {
541 		soisdisconnected(so);
542 #if DEVELOPMENT || DEBUG
543 		kcb->status = KCTL_DISCONNECTED;
544 #endif /* DEVELOPMENT || DEBUG */
545 		lck_mtx_lock(&ctl_mtx);
546 		TAILQ_REMOVE(&kctl->kcb_head, kcb, next);
547 		kcb->kctl = NULL;
548 		kcb->sac.sc_unit = 0;
549 		kctlstat.kcs_pcbcount--;
550 		kctlstat.kcs_gencnt++;
551 		kctlstat.kcs_conn_fail++;
552 		lck_mtx_unlock(&ctl_mtx);
553 	}
554 	return error;
555 }
556 
557 static int
ctl_bind(struct socket * so,struct sockaddr * nam,struct proc * p)558 ctl_bind(struct socket *so, struct sockaddr *nam, struct proc *p)
559 {
560 	int error = 0;
561 	struct ctl_cb *kcb = (struct ctl_cb *)so->so_pcb;
562 
563 	if (kcb == NULL) {
564 		panic("ctl_bind so_pcb null");
565 	}
566 
567 	lck_mtx_t *mtx_held = socket_getlock(so, PR_F_WILLUNLOCK);
568 	ctl_kcb_increment_use_count(kcb, mtx_held);
569 	ctl_kcb_require_clearing(kcb, mtx_held);
570 
571 	error = ctl_setup_kctl(so, nam, p);
572 	if (error) {
573 		goto out;
574 	}
575 
576 	if (kcb->kctl == NULL) {
577 		panic("ctl_bind kctl null");
578 	}
579 
580 	if (kcb->kctl->bind == NULL) {
581 		error = EINVAL;
582 		goto out;
583 	}
584 
585 	socket_unlock(so, 0);
586 	error = (*kcb->kctl->bind)(kcb->kctl->kctlref, &kcb->sac, &kcb->userdata);
587 	socket_lock(so, 0);
588 
589 out:
590 	ctl_kcb_done_clearing(kcb);
591 	ctl_kcb_decrement_use_count(kcb);
592 	return error;
593 }
594 
595 static int
ctl_connect(struct socket * so,struct sockaddr * nam,struct proc * p)596 ctl_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
597 {
598 	int error = 0;
599 	struct ctl_cb *kcb = (struct ctl_cb *)so->so_pcb;
600 
601 	if (kcb == NULL) {
602 		panic("ctl_connect so_pcb null");
603 	}
604 
605 	lck_mtx_t *mtx_held = socket_getlock(so, PR_F_WILLUNLOCK);
606 	ctl_kcb_increment_use_count(kcb, mtx_held);
607 	ctl_kcb_require_clearing(kcb, mtx_held);
608 
609 #if DEVELOPMENT || DEBUG
610 	if (kcb->status != KCTL_DISCONNECTED && ctl_panic_debug) {
611 		panic("kctl already connecting/connected");
612 	}
613 	kcb->status = KCTL_CONNECTING;
614 #endif /* DEVELOPMENT || DEBUG */
615 
616 	error = ctl_setup_kctl(so, nam, p);
617 	if (error) {
618 		goto out;
619 	}
620 
621 	if (kcb->kctl == NULL) {
622 		panic("ctl_connect kctl null");
623 	}
624 
625 	soisconnecting(so);
626 	socket_unlock(so, 0);
627 	error = (*kcb->kctl->connect)(kcb->kctl->kctlref, &kcb->sac, &kcb->userdata);
628 	socket_lock(so, 0);
629 	if (error) {
630 		goto end;
631 	}
632 	soisconnected(so);
633 #if DEVELOPMENT || DEBUG
634 	kcb->status = KCTL_CONNECTED;
635 #endif /* DEVELOPMENT || DEBUG */
636 
637 end:
638 	if (error && kcb->kctl->disconnect) {
639 		/*
640 		 * XXX Make sure we Don't check the return value
641 		 * of disconnect here.
642 		 * ipsec/utun_ctl_disconnect will return error when
643 		 * disconnect gets called after connect failure.
644 		 * However if we decide to check for disconnect return
645 		 * value here. Please make sure to revisit
646 		 * ipsec/utun_ctl_disconnect.
647 		 */
648 		socket_unlock(so, 0);
649 		(*kcb->kctl->disconnect)(kcb->kctl->kctlref, kcb->sac.sc_unit, kcb->userdata);
650 		socket_lock(so, 0);
651 	}
652 	if (error) {
653 		soisdisconnected(so);
654 #if DEVELOPMENT || DEBUG
655 		kcb->status = KCTL_DISCONNECTED;
656 #endif /* DEVELOPMENT || DEBUG */
657 		lck_mtx_lock(&ctl_mtx);
658 		TAILQ_REMOVE(&kcb->kctl->kcb_head, kcb, next);
659 		kcb->kctl = NULL;
660 		kcb->sac.sc_unit = 0;
661 		kctlstat.kcs_pcbcount--;
662 		kctlstat.kcs_gencnt++;
663 		kctlstat.kcs_conn_fail++;
664 		lck_mtx_unlock(&ctl_mtx);
665 	}
666 out:
667 	ctl_kcb_done_clearing(kcb);
668 	ctl_kcb_decrement_use_count(kcb);
669 	return error;
670 }
671 
672 static int
ctl_disconnect(struct socket * so)673 ctl_disconnect(struct socket *so)
674 {
675 	struct ctl_cb   *kcb = (struct ctl_cb *)so->so_pcb;
676 
677 	if ((kcb = (struct ctl_cb *)so->so_pcb)) {
678 		lck_mtx_t *mtx_held = socket_getlock(so, PR_F_WILLUNLOCK);
679 		ctl_kcb_increment_use_count(kcb, mtx_held);
680 		ctl_kcb_require_clearing(kcb, mtx_held);
681 		struct kctl             *kctl = kcb->kctl;
682 
683 		if (kctl && kctl->disconnect) {
684 			socket_unlock(so, 0);
685 			(*kctl->disconnect)(kctl->kctlref, kcb->sac.sc_unit,
686 			    kcb->userdata);
687 			socket_lock(so, 0);
688 		}
689 
690 		soisdisconnected(so);
691 #if DEVELOPMENT || DEBUG
692 		kcb->status = KCTL_DISCONNECTED;
693 #endif /* DEVELOPMENT || DEBUG */
694 
695 		socket_unlock(so, 0);
696 		lck_mtx_lock(&ctl_mtx);
697 		kcb->kctl = 0;
698 		kcb->sac.sc_unit = 0;
699 		while (kcb->usecount != 0) {
700 			msleep(&kcb->usecount, &ctl_mtx, 0, "kcb->usecount", 0);
701 		}
702 		TAILQ_REMOVE(&kctl->kcb_head, kcb, next);
703 		kctlstat.kcs_pcbcount--;
704 		kctlstat.kcs_gencnt++;
705 		lck_mtx_unlock(&ctl_mtx);
706 		socket_lock(so, 0);
707 		ctl_kcb_done_clearing(kcb);
708 		ctl_kcb_decrement_use_count(kcb);
709 	}
710 	return 0;
711 }
712 
713 static int
ctl_peeraddr(struct socket * so,struct sockaddr ** nam)714 ctl_peeraddr(struct socket *so, struct sockaddr **nam)
715 {
716 	struct ctl_cb           *kcb = (struct ctl_cb *)so->so_pcb;
717 	struct kctl                     *kctl;
718 	struct sockaddr_ctl     sc;
719 
720 	if (kcb == NULL) {      /* sanity check */
721 		return ENOTCONN;
722 	}
723 
724 	if ((kctl = kcb->kctl) == NULL) {
725 		return EINVAL;
726 	}
727 
728 	bzero(&sc, sizeof(struct sockaddr_ctl));
729 	sc.sc_len = sizeof(struct sockaddr_ctl);
730 	sc.sc_family = AF_SYSTEM;
731 	sc.ss_sysaddr = AF_SYS_CONTROL;
732 	sc.sc_id =  kctl->id;
733 	sc.sc_unit = kcb->sac.sc_unit;
734 
735 	*nam = dup_sockaddr((struct sockaddr *)&sc, 1);
736 
737 	return 0;
738 }
739 
740 static void
ctl_sbrcv_trim(struct socket * so)741 ctl_sbrcv_trim(struct socket *so)
742 {
743 	struct sockbuf *sb = &so->so_rcv;
744 
745 	if (sb->sb_hiwat > sb->sb_idealsize) {
746 		u_int32_t diff;
747 		int32_t trim;
748 
749 		/*
750 		 * The difference between the ideal size and the
751 		 * current size is the upper bound of the trimage
752 		 */
753 		diff = sb->sb_hiwat - sb->sb_idealsize;
754 		/*
755 		 * We cannot trim below the outstanding data
756 		 */
757 		trim = sb->sb_hiwat - sb->sb_cc;
758 
759 		trim = imin(trim, (int32_t)diff);
760 
761 		if (trim > 0) {
762 			sbreserve(sb, (sb->sb_hiwat - trim));
763 
764 			if (ctl_debug) {
765 				printf("%s - shrunk to %d\n",
766 				    __func__, sb->sb_hiwat);
767 			}
768 		}
769 	}
770 }
771 
772 static int
ctl_usr_rcvd(struct socket * so,int flags)773 ctl_usr_rcvd(struct socket *so, int flags)
774 {
775 	int                     error = 0;
776 	struct ctl_cb           *kcb = (struct ctl_cb *)so->so_pcb;
777 	struct kctl                     *kctl;
778 
779 	if (kcb == NULL) {
780 		return ENOTCONN;
781 	}
782 
783 	lck_mtx_t *mtx_held = socket_getlock(so, PR_F_WILLUNLOCK);
784 	ctl_kcb_increment_use_count(kcb, mtx_held);
785 
786 	if ((kctl = kcb->kctl) == NULL) {
787 		error = EINVAL;
788 		goto out;
789 	}
790 
791 	if (kctl->rcvd) {
792 		socket_unlock(so, 0);
793 		(*kctl->rcvd)(kctl->kctlref, kcb->sac.sc_unit, kcb->userdata, flags);
794 		socket_lock(so, 0);
795 	}
796 
797 	ctl_sbrcv_trim(so);
798 
799 out:
800 	ctl_kcb_decrement_use_count(kcb);
801 	return error;
802 }
803 
804 static int
ctl_send(struct socket * so,int flags,struct mbuf * m,struct sockaddr * addr,struct mbuf * control,struct proc * p)805 ctl_send(struct socket *so, int flags, struct mbuf *m,
806     struct sockaddr *addr, struct mbuf *control,
807     struct proc *p)
808 {
809 #pragma unused(addr, p)
810 	int             error = 0;
811 	struct ctl_cb   *kcb = (struct ctl_cb *)so->so_pcb;
812 	struct kctl     *kctl;
813 
814 	if (control) {
815 		m_freem(control);
816 	}
817 
818 	if (kcb == NULL) {      /* sanity check */
819 		m_freem(m);
820 		return ENOTCONN;
821 	}
822 
823 	lck_mtx_t *mtx_held = socket_getlock(so, PR_F_WILLUNLOCK);
824 	ctl_kcb_increment_use_count(kcb, mtx_held);
825 
826 	if (error == 0 && (kctl = kcb->kctl) == NULL) {
827 		error = EINVAL;
828 	}
829 
830 	if (error == 0 && kctl->send) {
831 		so_tc_update_stats(m, so, m_get_service_class(m));
832 		socket_unlock(so, 0);
833 		error = (*kctl->send)(kctl->kctlref, kcb->sac.sc_unit, kcb->userdata,
834 		    m, flags);
835 		socket_lock(so, 0);
836 	} else {
837 		m_freem(m);
838 		if (error == 0) {
839 			error = ENOTSUP;
840 		}
841 	}
842 	if (error != 0) {
843 		OSIncrementAtomic64((SInt64 *)&kctlstat.kcs_send_fail);
844 	}
845 	ctl_kcb_decrement_use_count(kcb);
846 
847 	return error;
848 }
849 
850 static int
ctl_send_list(struct socket * so,struct mbuf * m,u_int * pktcnt,int flags)851 ctl_send_list(struct socket *so, struct mbuf *m, u_int *pktcnt, int flags)
852 {
853 	int             error = 0;
854 	struct ctl_cb   *kcb = (struct ctl_cb *)so->so_pcb;
855 	struct kctl     *kctl;
856 	const bool      update_tc = SOCK_DOM(so) == PF_INET || SOCK_DOM(so) == PF_INET6;
857 
858 	if (kcb == NULL) {      /* sanity check */
859 		m_freem_list(m);
860 		return ENOTCONN;
861 	}
862 
863 	lck_mtx_t *mtx_held = socket_getlock(so, PR_F_WILLUNLOCK);
864 	ctl_kcb_increment_use_count(kcb, mtx_held);
865 
866 	if ((kctl = kcb->kctl) == NULL) {
867 		error = EINVAL;
868 		goto done;
869 	}
870 
871 	if (kctl->send_list != NULL) {
872 		struct mbuf *nxt;
873 
874 		for (nxt = m; update_tc && nxt != NULL; nxt = nxt->m_nextpkt) {
875 			so_tc_update_stats(nxt, so, m_get_service_class(nxt));
876 		}
877 
878 		socket_unlock(so, 0);
879 		error = (*kctl->send_list)(kctl->kctlref, kcb->sac.sc_unit,
880 		    kcb->userdata, m, flags);
881 		socket_lock(so, 0);
882 	} else {
883 		*pktcnt = 0;
884 		while (m != NULL && error == 0) {
885 			struct mbuf *nextpkt = m->m_nextpkt;
886 
887 			m->m_nextpkt = NULL;
888 
889 			if (update_tc) {
890 				so_tc_update_stats(m, so, m_get_service_class(m));
891 			}
892 			socket_unlock(so, 0);
893 			error = (*kctl->send)(kctl->kctlref, kcb->sac.sc_unit,
894 			    kcb->userdata, m, flags);
895 			socket_lock(so, 0);
896 			m = nextpkt;
897 			if (error == 0) {
898 				*pktcnt += 1;
899 			}
900 		}
901 		if (m != NULL) {
902 			m_freem_list(m);
903 		}
904 	}
905 done:
906 	if (error != 0) {
907 		OSIncrementAtomic64((SInt64 *)&kctlstat.kcs_send_list_fail);
908 	}
909 	ctl_kcb_decrement_use_count(kcb);
910 
911 	return error;
912 }
913 
914 static errno_t
ctl_rcvbspace(struct socket * so,size_t datasize,u_int32_t kctlflags,u_int32_t flags)915 ctl_rcvbspace(struct socket *so, size_t datasize,
916     u_int32_t kctlflags, u_int32_t flags)
917 {
918 	struct sockbuf *sb = &so->so_rcv;
919 	u_int32_t space = sbspace(sb);
920 	errno_t error;
921 
922 	if ((kctlflags & CTL_FLAG_REG_CRIT) == 0) {
923 		if ((u_int32_t) space >= datasize) {
924 			error = 0;
925 		} else {
926 			error = ENOBUFS;
927 		}
928 	} else if ((flags & CTL_DATA_CRIT) == 0) {
929 		/*
930 		 * Reserve 25% for critical messages
931 		 */
932 		if (space < (sb->sb_hiwat >> 2) ||
933 		    space < datasize) {
934 			error = ENOBUFS;
935 		} else {
936 			error = 0;
937 		}
938 	} else {
939 		size_t autorcvbuf_max;
940 
941 		/*
942 		 * Allow overcommit of 25%
943 		 */
944 		autorcvbuf_max = min(sb->sb_idealsize + (sb->sb_idealsize >> 2),
945 		    ctl_autorcvbuf_max);
946 
947 		if ((u_int32_t) space >= datasize) {
948 			error = 0;
949 		} else if (tcp_cansbgrow(sb) &&
950 		    sb->sb_hiwat < autorcvbuf_max) {
951 			/*
952 			 * Grow with a little bit of leeway
953 			 */
954 			size_t grow = datasize - space + _MSIZE;
955 			u_int32_t cc = (u_int32_t)MIN(MIN((sb->sb_hiwat + grow), autorcvbuf_max), UINT32_MAX);
956 
957 			if (sbreserve(sb, cc) == 1) {
958 				if (sb->sb_hiwat > ctl_autorcvbuf_high) {
959 					ctl_autorcvbuf_high = sb->sb_hiwat;
960 				}
961 
962 				/*
963 				 * A final check
964 				 */
965 				if ((u_int32_t) sbspace(sb) >= datasize) {
966 					error = 0;
967 				} else {
968 					error = ENOBUFS;
969 				}
970 
971 				if (ctl_debug) {
972 					printf("%s - grown to %d error %d\n",
973 					    __func__, sb->sb_hiwat, error);
974 				}
975 			} else {
976 				error = ENOBUFS;
977 			}
978 		} else {
979 			error = ENOBUFS;
980 		}
981 	}
982 	return error;
983 }
984 
985 errno_t
ctl_enqueuembuf(kern_ctl_ref kctlref,u_int32_t unit,struct mbuf * m,u_int32_t flags)986 ctl_enqueuembuf(kern_ctl_ref kctlref, u_int32_t unit, struct mbuf *m,
987     u_int32_t flags)
988 {
989 	struct socket   *so;
990 	errno_t         error = 0;
991 	int             len = m->m_pkthdr.len;
992 	u_int32_t       kctlflags;
993 
994 	so = kcb_find_socket(kctlref, unit, &kctlflags);
995 	if (so == NULL) {
996 		return EINVAL;
997 	}
998 
999 	if (ctl_rcvbspace(so, len, kctlflags, flags) != 0) {
1000 		error = ENOBUFS;
1001 		OSIncrementAtomic64((SInt64 *)&kctlstat.kcs_enqueue_fullsock);
1002 		goto bye;
1003 	}
1004 	if ((flags & CTL_DATA_EOR)) {
1005 		m->m_flags |= M_EOR;
1006 	}
1007 
1008 	so_recv_data_stat(so, m, 0);
1009 	if (sbappend_nodrop(&so->so_rcv, m) != 0) {
1010 		if ((flags & CTL_DATA_NOWAKEUP) == 0) {
1011 			sorwakeup(so);
1012 		}
1013 	} else {
1014 		error = ENOBUFS;
1015 		OSIncrementAtomic64((SInt64 *)&kctlstat.kcs_enqueue_fullsock);
1016 	}
1017 bye:
1018 	if (ctl_debug && error != 0 && (flags & CTL_DATA_CRIT)) {
1019 		printf("%s - crit data err %d len %d hiwat %d cc: %d\n",
1020 		    __func__, error, len,
1021 		    so->so_rcv.sb_hiwat, so->so_rcv.sb_cc);
1022 	}
1023 
1024 	socket_unlock(so, 1);
1025 	if (error != 0) {
1026 		OSIncrementAtomic64((SInt64 *)&kctlstat.kcs_enqueue_fail);
1027 	}
1028 
1029 	return error;
1030 }
1031 
1032 /*
1033  * Compute space occupied by mbuf like sbappendrecord
1034  */
1035 static int
m_space(struct mbuf * m)1036 m_space(struct mbuf *m)
1037 {
1038 	int space = 0;
1039 	struct mbuf *nxt;
1040 
1041 	for (nxt = m; nxt != NULL; nxt = nxt->m_next) {
1042 		space += nxt->m_len;
1043 	}
1044 
1045 	return space;
1046 }
1047 
1048 errno_t
ctl_enqueuembuf_list(void * kctlref,u_int32_t unit,struct mbuf * m_list,u_int32_t flags,struct mbuf ** m_remain)1049 ctl_enqueuembuf_list(void *kctlref, u_int32_t unit, struct mbuf *m_list,
1050     u_int32_t flags, struct mbuf **m_remain)
1051 {
1052 	struct socket *so = NULL;
1053 	errno_t error = 0;
1054 	struct mbuf *m, *nextpkt;
1055 	int needwakeup = 0;
1056 	int len = 0;
1057 	u_int32_t kctlflags;
1058 
1059 	/*
1060 	 * Need to point the beginning of the list in case of early exit
1061 	 */
1062 	m = m_list;
1063 
1064 	/*
1065 	 * kcb_find_socket takes the socket lock with a reference
1066 	 */
1067 	so = kcb_find_socket(kctlref, unit, &kctlflags);
1068 	if (so == NULL) {
1069 		error = EINVAL;
1070 		goto done;
1071 	}
1072 
1073 	if (kctlflags & CTL_FLAG_REG_SOCK_STREAM) {
1074 		error = EOPNOTSUPP;
1075 		goto done;
1076 	}
1077 	if (flags & CTL_DATA_EOR) {
1078 		error = EINVAL;
1079 		goto done;
1080 	}
1081 
1082 	for (m = m_list; m != NULL; m = nextpkt) {
1083 		nextpkt = m->m_nextpkt;
1084 
1085 		if (m->m_pkthdr.len == 0 && ctl_debug) {
1086 			printf("%s: %llx m_pkthdr.len is 0",
1087 			    __func__, (uint64_t)VM_KERNEL_ADDRPERM(m));
1088 		}
1089 
1090 		/*
1091 		 * The mbuf is either appended or freed by sbappendrecord()
1092 		 * so it's not reliable from a data standpoint
1093 		 */
1094 		len = m_space(m);
1095 		if (ctl_rcvbspace(so, len, kctlflags, flags) != 0) {
1096 			error = ENOBUFS;
1097 			OSIncrementAtomic64(
1098 				(SInt64 *)&kctlstat.kcs_enqueue_fullsock);
1099 			break;
1100 		} else {
1101 			/*
1102 			 * Unlink from the list, m is on its own
1103 			 */
1104 			m->m_nextpkt = NULL;
1105 			so_recv_data_stat(so, m, 0);
1106 			if (sbappendrecord_nodrop(&so->so_rcv, m) != 0) {
1107 				needwakeup = 1;
1108 			} else {
1109 				/*
1110 				 * We free or return the remaining
1111 				 * mbufs in the list
1112 				 */
1113 				m = nextpkt;
1114 				error = ENOBUFS;
1115 				OSIncrementAtomic64(
1116 					(SInt64 *)&kctlstat.kcs_enqueue_fullsock);
1117 				break;
1118 			}
1119 		}
1120 	}
1121 	if (needwakeup && (flags & CTL_DATA_NOWAKEUP) == 0) {
1122 		sorwakeup(so);
1123 	}
1124 
1125 done:
1126 	if (so != NULL) {
1127 		if (ctl_debug && error != 0 && (flags & CTL_DATA_CRIT)) {
1128 			printf("%s - crit data err %d len %d hiwat %d cc: %d\n",
1129 			    __func__, error, len,
1130 			    so->so_rcv.sb_hiwat, so->so_rcv.sb_cc);
1131 		}
1132 
1133 		socket_unlock(so, 1);
1134 	}
1135 	if (m_remain) {
1136 		*m_remain = m;
1137 
1138 		if (m != NULL && socket_debug && so != NULL &&
1139 		    (so->so_options & SO_DEBUG)) {
1140 			struct mbuf *n;
1141 
1142 			printf("%s m_list %llx\n", __func__,
1143 			    (uint64_t) VM_KERNEL_ADDRPERM(m_list));
1144 			for (n = m; n != NULL; n = n->m_nextpkt) {
1145 				printf(" remain %llx m_next %llx\n",
1146 				    (uint64_t) VM_KERNEL_ADDRPERM(n),
1147 				    (uint64_t) VM_KERNEL_ADDRPERM(n->m_next));
1148 			}
1149 		}
1150 	} else {
1151 		if (m != NULL) {
1152 			m_freem_list(m);
1153 		}
1154 	}
1155 	if (error != 0) {
1156 		OSIncrementAtomic64((SInt64 *)&kctlstat.kcs_enqueue_fail);
1157 	}
1158 	return error;
1159 }
1160 
1161 errno_t
ctl_enqueuedata(void * kctlref,u_int32_t unit,void * data,size_t len,u_int32_t flags)1162 ctl_enqueuedata(void *kctlref, u_int32_t unit, void *data, size_t len,
1163     u_int32_t flags)
1164 {
1165 	struct socket   *so;
1166 	struct mbuf     *m;
1167 	errno_t         error = 0;
1168 	unsigned int    num_needed;
1169 	struct mbuf     *n;
1170 	size_t          curlen = 0;
1171 	u_int32_t       kctlflags;
1172 
1173 	so = kcb_find_socket(kctlref, unit, &kctlflags);
1174 	if (so == NULL) {
1175 		return EINVAL;
1176 	}
1177 
1178 	if (ctl_rcvbspace(so, len, kctlflags, flags) != 0) {
1179 		error = ENOBUFS;
1180 		OSIncrementAtomic64((SInt64 *)&kctlstat.kcs_enqueue_fullsock);
1181 		goto bye;
1182 	}
1183 
1184 	num_needed = 1;
1185 	m = m_allocpacket_internal(&num_needed, len, NULL, M_NOWAIT, 1, 0);
1186 	if (m == NULL) {
1187 		kctlstat.kcs_enqdata_mb_alloc_fail++;
1188 		if (ctl_debug) {
1189 			printf("%s: m_allocpacket_internal(%lu) failed\n",
1190 			    __func__, len);
1191 		}
1192 		error = ENOMEM;
1193 		goto bye;
1194 	}
1195 
1196 	for (n = m; n != NULL; n = n->m_next) {
1197 		size_t mlen = mbuf_maxlen(n);
1198 
1199 		if (mlen + curlen > len) {
1200 			mlen = len - curlen;
1201 		}
1202 		n->m_len = (int32_t)mlen;
1203 		bcopy((char *)data + curlen, n->m_data, mlen);
1204 		curlen += mlen;
1205 	}
1206 	mbuf_pkthdr_setlen(m, curlen);
1207 
1208 	if ((flags & CTL_DATA_EOR)) {
1209 		m->m_flags |= M_EOR;
1210 	}
1211 	so_recv_data_stat(so, m, 0);
1212 	/*
1213 	 * No need to call the "nodrop" variant of sbappend
1214 	 * because the mbuf is local to the scope of the function
1215 	 */
1216 	if (sbappend(&so->so_rcv, m) != 0) {
1217 		if ((flags & CTL_DATA_NOWAKEUP) == 0) {
1218 			sorwakeup(so);
1219 		}
1220 	} else {
1221 		kctlstat.kcs_enqdata_sbappend_fail++;
1222 		error = ENOBUFS;
1223 		OSIncrementAtomic64((SInt64 *)&kctlstat.kcs_enqueue_fullsock);
1224 	}
1225 
1226 bye:
1227 	if (ctl_debug && error != 0 && (flags & CTL_DATA_CRIT)) {
1228 		printf("%s - crit data err %d len %d hiwat %d cc: %d\n",
1229 		    __func__, error, (int)len,
1230 		    so->so_rcv.sb_hiwat, so->so_rcv.sb_cc);
1231 	}
1232 
1233 	socket_unlock(so, 1);
1234 	if (error != 0) {
1235 		OSIncrementAtomic64((SInt64 *)&kctlstat.kcs_enqueue_fail);
1236 	}
1237 	return error;
1238 }
1239 
1240 errno_t
ctl_getenqueuepacketcount(kern_ctl_ref kctlref,u_int32_t unit,u_int32_t * pcnt)1241 ctl_getenqueuepacketcount(kern_ctl_ref kctlref, u_int32_t unit, u_int32_t *pcnt)
1242 {
1243 	struct socket   *so;
1244 	u_int32_t cnt;
1245 	struct mbuf *m1;
1246 
1247 	if (pcnt == NULL) {
1248 		return EINVAL;
1249 	}
1250 
1251 	so = kcb_find_socket(kctlref, unit, NULL);
1252 	if (so == NULL) {
1253 		return EINVAL;
1254 	}
1255 
1256 	cnt = 0;
1257 	m1 = so->so_rcv.sb_mb;
1258 	while (m1 != NULL) {
1259 		if (m1->m_type == MT_DATA ||
1260 		    m1->m_type == MT_HEADER ||
1261 		    m1->m_type == MT_OOBDATA) {
1262 			cnt += 1;
1263 		}
1264 		m1 = m1->m_nextpkt;
1265 	}
1266 	*pcnt = cnt;
1267 
1268 	socket_unlock(so, 1);
1269 
1270 	return 0;
1271 }
1272 
1273 errno_t
ctl_getenqueuespace(kern_ctl_ref kctlref,u_int32_t unit,size_t * space)1274 ctl_getenqueuespace(kern_ctl_ref kctlref, u_int32_t unit, size_t *space)
1275 {
1276 	struct socket   *so;
1277 	long avail;
1278 
1279 	if (space == NULL) {
1280 		return EINVAL;
1281 	}
1282 
1283 	so = kcb_find_socket(kctlref, unit, NULL);
1284 	if (so == NULL) {
1285 		return EINVAL;
1286 	}
1287 
1288 	avail = sbspace(&so->so_rcv);
1289 	*space = (avail < 0) ? 0 : avail;
1290 	socket_unlock(so, 1);
1291 
1292 	return 0;
1293 }
1294 
1295 errno_t
ctl_getenqueuereadable(kern_ctl_ref kctlref,u_int32_t unit,u_int32_t * difference)1296 ctl_getenqueuereadable(kern_ctl_ref kctlref, u_int32_t unit,
1297     u_int32_t *difference)
1298 {
1299 	struct socket   *so;
1300 
1301 	if (difference == NULL) {
1302 		return EINVAL;
1303 	}
1304 
1305 	so = kcb_find_socket(kctlref, unit, NULL);
1306 	if (so == NULL) {
1307 		return EINVAL;
1308 	}
1309 
1310 	if (so->so_rcv.sb_cc >= so->so_rcv.sb_lowat) {
1311 		*difference = 0;
1312 	} else {
1313 		*difference = (so->so_rcv.sb_lowat - so->so_rcv.sb_cc);
1314 	}
1315 	socket_unlock(so, 1);
1316 
1317 	return 0;
1318 }
1319 
1320 static int
ctl_ctloutput(struct socket * so,struct sockopt * sopt)1321 ctl_ctloutput(struct socket *so, struct sockopt *sopt)
1322 {
1323 	struct ctl_cb   *kcb = (struct ctl_cb *)so->so_pcb;
1324 	struct kctl     *kctl;
1325 	int     error = 0;
1326 	void    *data = NULL;
1327 	size_t  data_len = 0;
1328 	size_t  len;
1329 
1330 	if (sopt->sopt_level != SYSPROTO_CONTROL) {
1331 		return EINVAL;
1332 	}
1333 
1334 	if (kcb == NULL) {      /* sanity check */
1335 		return ENOTCONN;
1336 	}
1337 
1338 	if ((kctl = kcb->kctl) == NULL) {
1339 		return EINVAL;
1340 	}
1341 
1342 	lck_mtx_t *mtx_held = socket_getlock(so, PR_F_WILLUNLOCK);
1343 	ctl_kcb_increment_use_count(kcb, mtx_held);
1344 
1345 	switch (sopt->sopt_dir) {
1346 	case SOPT_SET:
1347 		if (kctl->setopt == NULL) {
1348 			error = ENOTSUP;
1349 			goto out;
1350 		}
1351 		if (sopt->sopt_valsize != 0) {
1352 			data_len = sopt->sopt_valsize;
1353 			data = kalloc_data(data_len, Z_WAITOK | Z_ZERO);
1354 			if (data == NULL) {
1355 				data_len = 0;
1356 				error = ENOMEM;
1357 				goto out;
1358 			}
1359 			error = sooptcopyin(sopt, data,
1360 			    sopt->sopt_valsize, sopt->sopt_valsize);
1361 		}
1362 		if (error == 0) {
1363 			socket_unlock(so, 0);
1364 			error = (*kctl->setopt)(kctl->kctlref,
1365 			    kcb->sac.sc_unit, kcb->userdata, sopt->sopt_name,
1366 			    data, sopt->sopt_valsize);
1367 			socket_lock(so, 0);
1368 		}
1369 
1370 		kfree_data(data, data_len);
1371 		break;
1372 
1373 	case SOPT_GET:
1374 		if (kctl->getopt == NULL) {
1375 			error = ENOTSUP;
1376 			goto out;
1377 		}
1378 
1379 		if (sopt->sopt_valsize && sopt->sopt_val) {
1380 			data_len = sopt->sopt_valsize;
1381 			data = kalloc_data(data_len, Z_WAITOK | Z_ZERO);
1382 			if (data == NULL) {
1383 				data_len = 0;
1384 				error = ENOMEM;
1385 				goto out;
1386 			}
1387 			/*
1388 			 * 4108337 - copy user data in case the
1389 			 * kernel control needs it
1390 			 */
1391 			error = sooptcopyin(sopt, data,
1392 			    sopt->sopt_valsize, sopt->sopt_valsize);
1393 		}
1394 
1395 		if (error == 0) {
1396 			len = sopt->sopt_valsize;
1397 			socket_unlock(so, 0);
1398 			error = (*kctl->getopt)(kctl->kctlref, kcb->sac.sc_unit,
1399 			    kcb->userdata, sopt->sopt_name,
1400 			    data, &len);
1401 			if (data != NULL && len > sopt->sopt_valsize) {
1402 				panic_plain("ctl_ctloutput: ctl %s returned "
1403 				    "len (%lu) > sopt_valsize (%lu)\n",
1404 				    kcb->kctl->name, len,
1405 				    sopt->sopt_valsize);
1406 			}
1407 			socket_lock(so, 0);
1408 			if (error == 0) {
1409 				if (data != NULL) {
1410 					error = sooptcopyout(sopt, data, len);
1411 				} else {
1412 					sopt->sopt_valsize = len;
1413 				}
1414 			}
1415 		}
1416 
1417 		kfree_data(data, data_len);
1418 		break;
1419 	}
1420 
1421 out:
1422 	ctl_kcb_decrement_use_count(kcb);
1423 	return error;
1424 }
1425 
1426 static int
ctl_ioctl(struct socket * so,u_long cmd,caddr_t data,struct ifnet * ifp,struct proc * p)1427 ctl_ioctl(struct socket *so, u_long cmd, caddr_t data,
1428     struct ifnet *ifp, struct proc *p)
1429 {
1430 #pragma unused(so, ifp, p)
1431 	int     error = ENOTSUP;
1432 
1433 	switch (cmd) {
1434 	/* get the number of controllers */
1435 	case CTLIOCGCOUNT: {
1436 		struct kctl     *kctl;
1437 		u_int32_t n = 0;
1438 
1439 		lck_mtx_lock(&ctl_mtx);
1440 		TAILQ_FOREACH(kctl, &ctl_head, next)
1441 		n++;
1442 		lck_mtx_unlock(&ctl_mtx);
1443 
1444 		bcopy(&n, data, sizeof(n));
1445 		error = 0;
1446 		break;
1447 	}
1448 	case CTLIOCGINFO: {
1449 		struct ctl_info ctl_info;
1450 		struct kctl     *kctl = 0;
1451 		size_t name_len;
1452 
1453 		bcopy(data, &ctl_info, sizeof(ctl_info));
1454 		name_len = strnlen(ctl_info.ctl_name, MAX_KCTL_NAME);
1455 
1456 		if (name_len == 0 || name_len + 1 > MAX_KCTL_NAME) {
1457 			error = EINVAL;
1458 			break;
1459 		}
1460 		lck_mtx_lock(&ctl_mtx);
1461 		kctl = ctl_find_by_name(ctl_info.ctl_name);
1462 		lck_mtx_unlock(&ctl_mtx);
1463 		if (kctl == 0) {
1464 			error = ENOENT;
1465 			break;
1466 		}
1467 		ctl_info.ctl_id = kctl->id;
1468 		bcopy(&ctl_info, data, sizeof(ctl_info));
1469 		error = 0;
1470 		break;
1471 	}
1472 
1473 		/* add controls to get list of NKEs */
1474 	}
1475 
1476 	return error;
1477 }
1478 
1479 static void
kctl_tbl_grow(void)1480 kctl_tbl_grow(void)
1481 {
1482 	struct kctl **new_table;
1483 	uintptr_t new_size;
1484 
1485 	lck_mtx_assert(&ctl_mtx, LCK_MTX_ASSERT_OWNED);
1486 
1487 	if (kctl_tbl_growing) {
1488 		/* Another thread is allocating */
1489 		kctl_tbl_growing_waiting++;
1490 
1491 		do {
1492 			(void) msleep((caddr_t) &kctl_tbl_growing, &ctl_mtx,
1493 			    PSOCK | PCATCH, "kctl_tbl_growing", 0);
1494 		} while (kctl_tbl_growing);
1495 		kctl_tbl_growing_waiting--;
1496 	}
1497 	/* Another thread grew the table */
1498 	if (kctl_table != NULL && kctl_tbl_count < kctl_tbl_size) {
1499 		return;
1500 	}
1501 
1502 	/* Verify we have a sane size */
1503 	if (kctl_tbl_size + KCTL_TBL_INC >= UINT16_MAX) {
1504 		kctlstat.kcs_tbl_size_too_big++;
1505 		if (ctl_debug) {
1506 			printf("%s kctl_tbl_size %lu too big\n",
1507 			    __func__, kctl_tbl_size);
1508 		}
1509 		return;
1510 	}
1511 	kctl_tbl_growing = 1;
1512 
1513 	new_size = kctl_tbl_size + KCTL_TBL_INC;
1514 
1515 	lck_mtx_unlock(&ctl_mtx);
1516 	new_table = kalloc_type(struct kctl *, new_size, Z_WAITOK | Z_ZERO);
1517 	lck_mtx_lock(&ctl_mtx);
1518 
1519 	if (new_table != NULL) {
1520 		if (kctl_table != NULL) {
1521 			bcopy(kctl_table, new_table,
1522 			    kctl_tbl_size * sizeof(struct kctl *));
1523 
1524 			kfree_type(struct kctl *, kctl_tbl_size, kctl_table);
1525 		}
1526 		kctl_table = new_table;
1527 		kctl_tbl_size = new_size;
1528 	}
1529 
1530 	kctl_tbl_growing = 0;
1531 
1532 	if (kctl_tbl_growing_waiting) {
1533 		wakeup(&kctl_tbl_growing);
1534 	}
1535 }
1536 
1537 #define KCTLREF_INDEX_MASK 0x0000FFFF
1538 #define KCTLREF_GENCNT_MASK 0xFFFF0000
1539 #define KCTLREF_GENCNT_SHIFT 16
1540 
1541 static kern_ctl_ref
kctl_make_ref(struct kctl * kctl)1542 kctl_make_ref(struct kctl *kctl)
1543 {
1544 	uintptr_t i;
1545 
1546 	lck_mtx_assert(&ctl_mtx, LCK_MTX_ASSERT_OWNED);
1547 
1548 	if (kctl_tbl_count >= kctl_tbl_size) {
1549 		kctl_tbl_grow();
1550 	}
1551 
1552 	kctl->kctlref = NULL;
1553 	for (i = 0; i < kctl_tbl_size; i++) {
1554 		if (kctl_table[i] == NULL) {
1555 			uintptr_t ref;
1556 
1557 			/*
1558 			 * Reference is index plus one
1559 			 */
1560 			kctl_ref_gencnt += 1;
1561 
1562 			/*
1563 			 * Add generation count as salt to reference to prevent
1564 			 * use after deregister
1565 			 */
1566 			ref = ((kctl_ref_gencnt << KCTLREF_GENCNT_SHIFT) &
1567 			    KCTLREF_GENCNT_MASK) +
1568 			    ((i + 1) & KCTLREF_INDEX_MASK);
1569 
1570 			kctl->kctlref = (void *)(ref);
1571 			kctl_table[i] = kctl;
1572 			kctl_tbl_count++;
1573 			break;
1574 		}
1575 	}
1576 
1577 	if (kctl->kctlref == NULL) {
1578 		panic("%s no space in table", __func__);
1579 	}
1580 
1581 	if (ctl_debug > 0) {
1582 		printf("%s %p for %p\n",
1583 		    __func__, kctl->kctlref, kctl);
1584 	}
1585 
1586 	return kctl->kctlref;
1587 }
1588 
1589 static void
kctl_delete_ref(kern_ctl_ref kctlref)1590 kctl_delete_ref(kern_ctl_ref kctlref)
1591 {
1592 	/*
1593 	 * Reference is index plus one
1594 	 */
1595 	uintptr_t i = (((uintptr_t)kctlref) & KCTLREF_INDEX_MASK) - 1;
1596 
1597 	lck_mtx_assert(&ctl_mtx, LCK_MTX_ASSERT_OWNED);
1598 
1599 	if (i < kctl_tbl_size) {
1600 		struct kctl *kctl = kctl_table[i];
1601 
1602 		if (kctl->kctlref == kctlref) {
1603 			kctl_table[i] = NULL;
1604 			kctl_tbl_count--;
1605 		} else {
1606 			kctlstat.kcs_bad_kctlref++;
1607 		}
1608 	} else {
1609 		kctlstat.kcs_bad_kctlref++;
1610 	}
1611 }
1612 
1613 static struct kctl *
kctl_from_ref(kern_ctl_ref kctlref)1614 kctl_from_ref(kern_ctl_ref kctlref)
1615 {
1616 	/*
1617 	 * Reference is index plus one
1618 	 */
1619 	uintptr_t i = (((uintptr_t)kctlref) & KCTLREF_INDEX_MASK) - 1;
1620 	struct kctl *kctl = NULL;
1621 
1622 	lck_mtx_assert(&ctl_mtx, LCK_MTX_ASSERT_OWNED);
1623 
1624 	if (i >= kctl_tbl_size) {
1625 		kctlstat.kcs_bad_kctlref++;
1626 		return NULL;
1627 	}
1628 	kctl = kctl_table[i];
1629 	if (kctl->kctlref != kctlref) {
1630 		kctlstat.kcs_bad_kctlref++;
1631 		return NULL;
1632 	}
1633 	return kctl;
1634 }
1635 
1636 /*
1637  * Register/unregister a NKE
1638  */
1639 errno_t
ctl_register(struct kern_ctl_reg * userkctl,kern_ctl_ref * kctlref)1640 ctl_register(struct kern_ctl_reg *userkctl, kern_ctl_ref *kctlref)
1641 {
1642 	struct kctl     *kctl = NULL;
1643 	struct kctl     *kctl_next = NULL;
1644 	u_int32_t       id = 1;
1645 	size_t          name_len;
1646 	int             is_extended = 0;
1647 	int             is_setup = 0;
1648 
1649 	if (userkctl == NULL) { /* sanity check */
1650 		return EINVAL;
1651 	}
1652 	if (userkctl->ctl_connect == NULL) {
1653 		return EINVAL;
1654 	}
1655 	name_len = strlen(userkctl->ctl_name);
1656 	if (name_len == 0 || name_len + 1 > MAX_KCTL_NAME) {
1657 		return EINVAL;
1658 	}
1659 
1660 	kctl = kalloc_type(struct kctl, Z_WAITOK | Z_ZERO | Z_NOFAIL);
1661 
1662 	lck_mtx_lock(&ctl_mtx);
1663 
1664 	if (kctl_make_ref(kctl) == NULL) {
1665 		lck_mtx_unlock(&ctl_mtx);
1666 		kfree_type(struct kctl, kctl);
1667 		return ENOMEM;
1668 	}
1669 
1670 	/*
1671 	 * Kernel Control IDs
1672 	 *
1673 	 * CTL_FLAG_REG_ID_UNIT indicates the control ID and unit number are
1674 	 * static. If they do not exist, add them to the list in order. If the
1675 	 * flag is not set, we must find a new unique value. We assume the
1676 	 * list is in order. We find the last item in the list and add one. If
1677 	 * this leads to wrapping the id around, we start at the front of the
1678 	 * list and look for a gap.
1679 	 */
1680 
1681 	if ((userkctl->ctl_flags & CTL_FLAG_REG_ID_UNIT) == 0) {
1682 		/* Must dynamically assign an unused ID */
1683 
1684 		/* Verify the same name isn't already registered */
1685 		if (ctl_find_by_name(userkctl->ctl_name) != NULL) {
1686 			kctl_delete_ref(kctl->kctlref);
1687 			lck_mtx_unlock(&ctl_mtx);
1688 			kfree_type(struct kctl, kctl);
1689 			return EEXIST;
1690 		}
1691 
1692 		/* Start with 1 in case the list is empty */
1693 		id = 1;
1694 		kctl_next = TAILQ_LAST(&ctl_head, kctl_list);
1695 
1696 		if (kctl_next != NULL) {
1697 			/* List was not empty, add one to the last item */
1698 			id = kctl_next->id + 1;
1699 			kctl_next = NULL;
1700 
1701 			/*
1702 			 * If this wrapped the id number, start looking at
1703 			 * the front of the list for an unused id.
1704 			 */
1705 			if (id == 0) {
1706 				/* Find the next unused ID */
1707 				id = 1;
1708 
1709 				TAILQ_FOREACH(kctl_next, &ctl_head, next) {
1710 					if (kctl_next->id > id) {
1711 						/* We found a gap */
1712 						break;
1713 					}
1714 
1715 					id = kctl_next->id + 1;
1716 				}
1717 			}
1718 		}
1719 
1720 		userkctl->ctl_id = id;
1721 		kctl->id = id;
1722 		kctl->reg_unit = -1;
1723 	} else {
1724 		TAILQ_FOREACH(kctl_next, &ctl_head, next) {
1725 			if (kctl_next->id > userkctl->ctl_id) {
1726 				break;
1727 			}
1728 		}
1729 
1730 		if (ctl_find_by_id_unit(userkctl->ctl_id, userkctl->ctl_unit)) {
1731 			kctl_delete_ref(kctl->kctlref);
1732 			lck_mtx_unlock(&ctl_mtx);
1733 			kfree_type(struct kctl, kctl);
1734 			return EEXIST;
1735 		}
1736 		kctl->id = userkctl->ctl_id;
1737 		kctl->reg_unit = userkctl->ctl_unit;
1738 	}
1739 
1740 	is_extended = (userkctl->ctl_flags & CTL_FLAG_REG_EXTENDED);
1741 	is_setup = (userkctl->ctl_flags & CTL_FLAG_REG_SETUP);
1742 
1743 	strlcpy(kctl->name, userkctl->ctl_name, MAX_KCTL_NAME);
1744 	kctl->flags = userkctl->ctl_flags;
1745 
1746 	/*
1747 	 * Let the caller know the default send and receive sizes
1748 	 */
1749 	if (userkctl->ctl_sendsize == 0) {
1750 		kctl->sendbufsize = CTL_SENDSIZE;
1751 		userkctl->ctl_sendsize = kctl->sendbufsize;
1752 	} else {
1753 		kctl->sendbufsize = userkctl->ctl_sendsize;
1754 	}
1755 	if (userkctl->ctl_recvsize == 0) {
1756 		kctl->recvbufsize = CTL_RECVSIZE;
1757 		userkctl->ctl_recvsize = kctl->recvbufsize;
1758 	} else {
1759 		kctl->recvbufsize = userkctl->ctl_recvsize;
1760 	}
1761 
1762 	if (is_setup) {
1763 		kctl->setup = userkctl->ctl_setup;
1764 	}
1765 	kctl->bind = userkctl->ctl_bind;
1766 	kctl->connect = userkctl->ctl_connect;
1767 	kctl->disconnect = userkctl->ctl_disconnect;
1768 	kctl->send = userkctl->ctl_send;
1769 	kctl->setopt = userkctl->ctl_setopt;
1770 	kctl->getopt = userkctl->ctl_getopt;
1771 	if (is_extended) {
1772 		kctl->rcvd = userkctl->ctl_rcvd;
1773 		kctl->send_list = userkctl->ctl_send_list;
1774 	}
1775 
1776 	TAILQ_INIT(&kctl->kcb_head);
1777 
1778 	if (kctl_next) {
1779 		TAILQ_INSERT_BEFORE(kctl_next, kctl, next);
1780 	} else {
1781 		TAILQ_INSERT_TAIL(&ctl_head, kctl, next);
1782 	}
1783 
1784 	kctlstat.kcs_reg_count++;
1785 	kctlstat.kcs_gencnt++;
1786 
1787 	lck_mtx_unlock(&ctl_mtx);
1788 
1789 	*kctlref = kctl->kctlref;
1790 
1791 	ctl_post_msg(KEV_CTL_REGISTERED, kctl->id);
1792 	return 0;
1793 }
1794 
1795 errno_t
ctl_deregister(void * kctlref)1796 ctl_deregister(void *kctlref)
1797 {
1798 	struct kctl             *kctl;
1799 
1800 	lck_mtx_lock(&ctl_mtx);
1801 	if ((kctl = kctl_from_ref(kctlref)) == NULL) {
1802 		kctlstat.kcs_bad_kctlref++;
1803 		lck_mtx_unlock(&ctl_mtx);
1804 		if (ctl_debug != 0) {
1805 			printf("%s invalid kctlref %p\n",
1806 			    __func__, kctlref);
1807 		}
1808 		return EINVAL;
1809 	}
1810 
1811 	if (!TAILQ_EMPTY(&kctl->kcb_head)) {
1812 		lck_mtx_unlock(&ctl_mtx);
1813 		return EBUSY;
1814 	}
1815 
1816 	TAILQ_REMOVE(&ctl_head, kctl, next);
1817 
1818 	kctlstat.kcs_reg_count--;
1819 	kctlstat.kcs_gencnt++;
1820 
1821 	kctl_delete_ref(kctl->kctlref);
1822 	lck_mtx_unlock(&ctl_mtx);
1823 
1824 	ctl_post_msg(KEV_CTL_DEREGISTERED, kctl->id);
1825 	kfree_type(struct kctl, kctl);
1826 	return 0;
1827 }
1828 
1829 /*
1830  * Must be called with global ctl_mtx lock taked
1831  */
1832 static struct kctl *
ctl_find_by_name(const char * name)1833 ctl_find_by_name(const char *name)
1834 {
1835 	struct kctl     *kctl;
1836 
1837 	lck_mtx_assert(&ctl_mtx, LCK_MTX_ASSERT_OWNED);
1838 
1839 	TAILQ_FOREACH(kctl, &ctl_head, next)
1840 	if (strncmp(kctl->name, name, sizeof(kctl->name)) == 0) {
1841 		return kctl;
1842 	}
1843 
1844 	return NULL;
1845 }
1846 
1847 u_int32_t
ctl_id_by_name(const char * name)1848 ctl_id_by_name(const char *name)
1849 {
1850 	u_int32_t       ctl_id = 0;
1851 	struct kctl     *kctl;
1852 
1853 	lck_mtx_lock(&ctl_mtx);
1854 	kctl = ctl_find_by_name(name);
1855 	if (kctl) {
1856 		ctl_id = kctl->id;
1857 	}
1858 	lck_mtx_unlock(&ctl_mtx);
1859 
1860 	return ctl_id;
1861 }
1862 
1863 errno_t
ctl_name_by_id(u_int32_t id,char * out_name,size_t maxsize)1864 ctl_name_by_id(u_int32_t id, char *out_name, size_t maxsize)
1865 {
1866 	int             found = 0;
1867 	struct kctl *kctl;
1868 
1869 	lck_mtx_lock(&ctl_mtx);
1870 	TAILQ_FOREACH(kctl, &ctl_head, next) {
1871 		if (kctl->id == id) {
1872 			break;
1873 		}
1874 	}
1875 
1876 	if (kctl) {
1877 		if (maxsize > MAX_KCTL_NAME) {
1878 			maxsize = MAX_KCTL_NAME;
1879 		}
1880 		strlcpy(out_name, kctl->name, maxsize);
1881 		found = 1;
1882 	}
1883 	lck_mtx_unlock(&ctl_mtx);
1884 
1885 	return found ? 0 : ENOENT;
1886 }
1887 
1888 /*
1889  * Must be called with global ctl_mtx lock taked
1890  *
1891  */
1892 static struct kctl *
ctl_find_by_id_unit(u_int32_t id,u_int32_t unit)1893 ctl_find_by_id_unit(u_int32_t id, u_int32_t unit)
1894 {
1895 	struct kctl     *kctl;
1896 
1897 	lck_mtx_assert(&ctl_mtx, LCK_MTX_ASSERT_OWNED);
1898 
1899 	TAILQ_FOREACH(kctl, &ctl_head, next) {
1900 		if (kctl->id == id && (kctl->flags & CTL_FLAG_REG_ID_UNIT) == 0) {
1901 			return kctl;
1902 		} else if (kctl->id == id && kctl->reg_unit == unit) {
1903 			return kctl;
1904 		}
1905 	}
1906 	return NULL;
1907 }
1908 
1909 /*
1910  * Must be called with kernel controller lock taken
1911  */
1912 static struct ctl_cb *
kcb_find(struct kctl * kctl,u_int32_t unit)1913 kcb_find(struct kctl *kctl, u_int32_t unit)
1914 {
1915 	struct ctl_cb   *kcb;
1916 
1917 	lck_mtx_assert(&ctl_mtx, LCK_MTX_ASSERT_OWNED);
1918 
1919 	TAILQ_FOREACH(kcb, &kctl->kcb_head, next)
1920 	if (kcb->sac.sc_unit == unit) {
1921 		return kcb;
1922 	}
1923 
1924 	return NULL;
1925 }
1926 
1927 static struct socket *
kcb_find_socket(kern_ctl_ref kctlref,u_int32_t unit,u_int32_t * kctlflags)1928 kcb_find_socket(kern_ctl_ref kctlref, u_int32_t unit, u_int32_t *kctlflags)
1929 {
1930 	struct socket *so = NULL;
1931 	struct ctl_cb   *kcb;
1932 	void *lr_saved;
1933 	struct kctl *kctl;
1934 	int i;
1935 
1936 	lr_saved = __builtin_return_address(0);
1937 
1938 	lck_mtx_lock(&ctl_mtx);
1939 	/*
1940 	 * First validate the kctlref
1941 	 */
1942 	if ((kctl = kctl_from_ref(kctlref)) == NULL) {
1943 		kctlstat.kcs_bad_kctlref++;
1944 		lck_mtx_unlock(&ctl_mtx);
1945 		if (ctl_debug != 0) {
1946 			printf("%s invalid kctlref %p\n",
1947 			    __func__, kctlref);
1948 		}
1949 		return NULL;
1950 	}
1951 
1952 	kcb = kcb_find(kctl, unit);
1953 	if (kcb == NULL || kcb->kctl != kctl || (so = kcb->so) == NULL) {
1954 		lck_mtx_unlock(&ctl_mtx);
1955 		return NULL;
1956 	}
1957 	/*
1958 	 * This prevents the socket from being closed
1959 	 */
1960 	kcb->usecount++;
1961 	/*
1962 	 * Respect lock ordering: socket before ctl_mtx
1963 	 */
1964 	lck_mtx_unlock(&ctl_mtx);
1965 
1966 	socket_lock(so, 1);
1967 	/*
1968 	 * The socket lock history is more useful if we store
1969 	 * the address of the caller.
1970 	 */
1971 	i = (so->next_lock_lr + SO_LCKDBG_MAX - 1) % SO_LCKDBG_MAX;
1972 	so->lock_lr[i] = lr_saved;
1973 
1974 	lck_mtx_lock(&ctl_mtx);
1975 
1976 	if ((kctl = kctl_from_ref(kctlref)) == NULL || kcb->kctl == NULL) {
1977 		lck_mtx_unlock(&ctl_mtx);
1978 		socket_unlock(so, 1);
1979 		so = NULL;
1980 		lck_mtx_lock(&ctl_mtx);
1981 	} else if (kctlflags != NULL) {
1982 		*kctlflags = kctl->flags;
1983 	}
1984 
1985 	kcb->usecount--;
1986 	if (kcb->usecount == 0 && kcb->require_clearing_count != 0) {
1987 		wakeup((event_t)&kcb->usecount);
1988 	}
1989 
1990 	lck_mtx_unlock(&ctl_mtx);
1991 
1992 	return so;
1993 }
1994 
1995 static void
ctl_post_msg(u_int32_t event_code,u_int32_t id)1996 ctl_post_msg(u_int32_t event_code, u_int32_t id)
1997 {
1998 	struct ctl_event_data   ctl_ev_data;
1999 	struct kev_msg                  ev_msg;
2000 
2001 	lck_mtx_assert(&ctl_mtx, LCK_MTX_ASSERT_NOTOWNED);
2002 
2003 	bzero(&ev_msg, sizeof(struct kev_msg));
2004 	ev_msg.vendor_code = KEV_VENDOR_APPLE;
2005 
2006 	ev_msg.kev_class = KEV_SYSTEM_CLASS;
2007 	ev_msg.kev_subclass = KEV_CTL_SUBCLASS;
2008 	ev_msg.event_code = event_code;
2009 
2010 	/* common nke subclass data */
2011 	bzero(&ctl_ev_data, sizeof(ctl_ev_data));
2012 	ctl_ev_data.ctl_id = id;
2013 	ev_msg.dv[0].data_ptr = &ctl_ev_data;
2014 	ev_msg.dv[0].data_length = sizeof(ctl_ev_data);
2015 
2016 	ev_msg.dv[1].data_length = 0;
2017 
2018 	kev_post_msg(&ev_msg);
2019 }
2020 
2021 static int
ctl_lock(struct socket * so,int refcount,void * lr)2022 ctl_lock(struct socket *so, int refcount, void *lr)
2023 {
2024 	void *lr_saved;
2025 
2026 	if (lr == NULL) {
2027 		lr_saved = __builtin_return_address(0);
2028 	} else {
2029 		lr_saved = lr;
2030 	}
2031 
2032 	if (so->so_pcb != NULL) {
2033 		lck_mtx_lock(&((struct ctl_cb *)so->so_pcb)->mtx);
2034 	} else {
2035 		panic("ctl_lock: so=%p NO PCB! lr=%p lrh= %s",
2036 		    so, lr_saved, solockhistory_nr(so));
2037 		/* NOTREACHED */
2038 	}
2039 
2040 	if (so->so_usecount < 0) {
2041 		panic("ctl_lock: so=%p so_pcb=%p lr=%p ref=%x lrh= %s",
2042 		    so, so->so_pcb, lr_saved, so->so_usecount,
2043 		    solockhistory_nr(so));
2044 		/* NOTREACHED */
2045 	}
2046 
2047 	if (refcount) {
2048 		so->so_usecount++;
2049 	}
2050 
2051 	so->lock_lr[so->next_lock_lr] = lr_saved;
2052 	so->next_lock_lr = (so->next_lock_lr + 1) % SO_LCKDBG_MAX;
2053 	return 0;
2054 }
2055 
2056 static int
ctl_unlock(struct socket * so,int refcount,void * lr)2057 ctl_unlock(struct socket *so, int refcount, void *lr)
2058 {
2059 	void *lr_saved;
2060 	lck_mtx_t *mutex_held;
2061 
2062 	if (lr == NULL) {
2063 		lr_saved = __builtin_return_address(0);
2064 	} else {
2065 		lr_saved = lr;
2066 	}
2067 
2068 #if (MORE_KCTLLOCK_DEBUG && (DEVELOPMENT || DEBUG))
2069 	printf("ctl_unlock: so=%llx sopcb=%x lock=%llx ref=%u lr=%llx\n",
2070 	    (uint64_t)VM_KERNEL_ADDRPERM(so),
2071 	    (uint64_t)VM_KERNEL_ADDRPERM(so->so_pcb,
2072 	    (uint64_t)VM_KERNEL_ADDRPERM(&((struct ctl_cb *)so->so_pcb)->mtx),
2073 	    so->so_usecount, (uint64_t)VM_KERNEL_ADDRPERM(lr_saved));
2074 #endif /* (MORE_KCTLLOCK_DEBUG && (DEVELOPMENT || DEBUG)) */
2075 	if (refcount) {
2076 		so->so_usecount--;
2077 	}
2078 
2079 	if (so->so_usecount < 0) {
2080 		panic("ctl_unlock: so=%p usecount=%x lrh= %s",
2081 		    so, so->so_usecount, solockhistory_nr(so));
2082 		/* NOTREACHED */
2083 	}
2084 	if (so->so_pcb == NULL) {
2085 		panic("ctl_unlock: so=%p NO PCB usecount=%x lr=%p lrh= %s",
2086 		    so, so->so_usecount, (void *)lr_saved,
2087 		    solockhistory_nr(so));
2088 		/* NOTREACHED */
2089 	}
2090 	mutex_held = &((struct ctl_cb *)so->so_pcb)->mtx;
2091 
2092 	    lck_mtx_assert(mutex_held, LCK_MTX_ASSERT_OWNED);
2093 	    so->unlock_lr[so->next_unlock_lr] = lr_saved;
2094 	    so->next_unlock_lr = (so->next_unlock_lr + 1) % SO_LCKDBG_MAX;
2095 	    lck_mtx_unlock(mutex_held);
2096 
2097 	    if (so->so_usecount == 0) {
2098 		ctl_sofreelastref(so);
2099 	}
2100 
2101 	    return 0;
2102 }
2103 
2104 static lck_mtx_t *
2105 ctl_getlock(struct socket *so, int flags)
2106 {
2107 #pragma unused(flags)
2108         struct ctl_cb *kcb = (struct ctl_cb *)so->so_pcb;
2109 
2110         if (so->so_pcb) {
2111                 if (so->so_usecount < 0) {
2112                         panic("ctl_getlock: so=%p usecount=%x lrh= %s",
2113                             so, so->so_usecount, solockhistory_nr(so));
2114 		}
2115                 return &kcb->mtx;
2116 	} else {
2117                 panic("ctl_getlock: so=%p NULL NO so_pcb %s",
2118                     so, solockhistory_nr(so));
2119                 return so->so_proto->pr_domain->dom_mtx;
2120 	}
2121 }
2122 
2123 __private_extern__ int
2124 kctl_reg_list SYSCTL_HANDLER_ARGS
2125 {
2126 #pragma unused(oidp, arg1, arg2)
2127         int error = 0;
2128         u_int64_t i, n;
2129         struct xsystmgen xsg;
2130         void *buf = NULL;
2131         struct kctl *kctl;
2132         size_t item_size = ROUNDUP64(sizeof(struct xkctl_reg));
2133 
2134         buf = kalloc_data(item_size, Z_WAITOK | Z_ZERO | Z_NOFAIL);
2135 
2136         lck_mtx_lock(&ctl_mtx);
2137 
2138         n = kctlstat.kcs_reg_count;
2139 
2140         if (req->oldptr == USER_ADDR_NULL) {
2141                 req->oldidx = (size_t)(n + n / 8) * sizeof(struct xkctl_reg);
2142                 goto done;
2143 	}
2144         if (req->newptr != USER_ADDR_NULL) {
2145                 error = EPERM;
2146                 goto done;
2147 	}
2148         bzero(&xsg, sizeof(xsg));
2149         xsg.xg_len = sizeof(xsg);
2150         xsg.xg_count = n;
2151         xsg.xg_gen = kctlstat.kcs_gencnt;
2152         xsg.xg_sogen = so_gencnt;
2153         error = SYSCTL_OUT(req, &xsg, sizeof(xsg));
2154         if (error) {
2155                 goto done;
2156 	}
2157         /*
2158          * We are done if there is no pcb
2159          */
2160         if (n == 0) {
2161                 goto done;
2162 	}
2163 
2164         for (i = 0, kctl = TAILQ_FIRST(&ctl_head);
2165             i < n && kctl != NULL;
2166             i++, kctl = TAILQ_NEXT(kctl, next)) {
2167                 struct xkctl_reg *xkr = (struct xkctl_reg *)buf;
2168                 struct ctl_cb *kcb;
2169                 u_int32_t pcbcount = 0;
2170 
2171                 TAILQ_FOREACH(kcb, &kctl->kcb_head, next)
2172                 pcbcount++;
2173 
2174                 bzero(buf, item_size);
2175 
2176                 xkr->xkr_len = sizeof(struct xkctl_reg);
2177                 xkr->xkr_kind = XSO_KCREG;
2178                 xkr->xkr_id = kctl->id;
2179                 xkr->xkr_reg_unit = kctl->reg_unit;
2180                 xkr->xkr_flags = kctl->flags;
2181                 xkr->xkr_kctlref = (uint64_t)(kctl->kctlref);
2182                 xkr->xkr_recvbufsize = kctl->recvbufsize;
2183                 xkr->xkr_sendbufsize = kctl->sendbufsize;
2184                 xkr->xkr_lastunit = kctl->lastunit;
2185                 xkr->xkr_pcbcount = pcbcount;
2186                 xkr->xkr_connect = (uint64_t)VM_KERNEL_UNSLIDE(kctl->connect);
2187                 xkr->xkr_disconnect =
2188                     (uint64_t)VM_KERNEL_UNSLIDE(kctl->disconnect);
2189                 xkr->xkr_send = (uint64_t)VM_KERNEL_UNSLIDE(kctl->send);
2190                 xkr->xkr_send_list =
2191                     (uint64_t)VM_KERNEL_UNSLIDE(kctl->send_list);
2192                 xkr->xkr_setopt = (uint64_t)VM_KERNEL_UNSLIDE(kctl->setopt);
2193                 xkr->xkr_getopt = (uint64_t)VM_KERNEL_UNSLIDE(kctl->getopt);
2194                 xkr->xkr_rcvd = (uint64_t)VM_KERNEL_UNSLIDE(kctl->rcvd);
2195                 strlcpy(xkr->xkr_name, kctl->name, sizeof(xkr->xkr_name));
2196 
2197                 error = SYSCTL_OUT(req, buf, item_size);
2198 	}
2199 
2200         if (error == 0) {
2201                 /*
2202                  * Give the user an updated idea of our state.
2203                  * If the generation differs from what we told
2204                  * her before, she knows that something happened
2205                  * while we were processing this request, and it
2206                  * might be necessary to retry.
2207                  */
2208                 bzero(&xsg, sizeof(xsg));
2209                 xsg.xg_len = sizeof(xsg);
2210                 xsg.xg_count = n;
2211                 xsg.xg_gen = kctlstat.kcs_gencnt;
2212                 xsg.xg_sogen = so_gencnt;
2213                 error = SYSCTL_OUT(req, &xsg, sizeof(xsg));
2214                 if (error) {
2215                         goto done;
2216 		}
2217 	}
2218 
2219 done:
2220         lck_mtx_unlock(&ctl_mtx);
2221 
2222         kfree_data(buf, item_size);
2223 
2224         return error;
2225 }
2226 
2227 __private_extern__ int
2228 kctl_pcblist SYSCTL_HANDLER_ARGS
2229 {
2230 #pragma unused(oidp, arg1, arg2)
2231         int error = 0;
2232         u_int64_t n, i;
2233         struct xsystmgen xsg;
2234         void *buf = NULL;
2235         struct kctl *kctl;
2236         size_t item_size = ROUNDUP64(sizeof(struct xkctlpcb)) +
2237             ROUNDUP64(sizeof(struct xsocket_n)) +
2238             2 * ROUNDUP64(sizeof(struct xsockbuf_n)) +
2239             ROUNDUP64(sizeof(struct xsockstat_n));
2240 
2241         buf = kalloc_data(item_size, Z_WAITOK | Z_ZERO | Z_NOFAIL);
2242 
2243         lck_mtx_lock(&ctl_mtx);
2244 
2245         n = kctlstat.kcs_pcbcount;
2246 
2247         if (req->oldptr == USER_ADDR_NULL) {
2248                 req->oldidx = (size_t)(n + n / 8) * item_size;
2249                 goto done;
2250 	}
2251         if (req->newptr != USER_ADDR_NULL) {
2252                 error = EPERM;
2253                 goto done;
2254 	}
2255         bzero(&xsg, sizeof(xsg));
2256         xsg.xg_len = sizeof(xsg);
2257         xsg.xg_count = n;
2258         xsg.xg_gen = kctlstat.kcs_gencnt;
2259         xsg.xg_sogen = so_gencnt;
2260         error = SYSCTL_OUT(req, &xsg, sizeof(xsg));
2261         if (error) {
2262                 goto done;
2263 	}
2264         /*
2265          * We are done if there is no pcb
2266          */
2267         if (n == 0) {
2268                 goto done;
2269 	}
2270 
2271         for (i = 0, kctl = TAILQ_FIRST(&ctl_head);
2272             i < n && kctl != NULL;
2273             kctl = TAILQ_NEXT(kctl, next)) {
2274                 struct ctl_cb *kcb;
2275 
2276                 for (kcb = TAILQ_FIRST(&kctl->kcb_head);
2277                     i < n && kcb != NULL;
2278                     i++, kcb = TAILQ_NEXT(kcb, next)) {
2279                         struct xkctlpcb *xk = (struct xkctlpcb *)buf;
2280                         struct xsocket_n *xso = (struct xsocket_n *)
2281                             ADVANCE64(xk, sizeof(*xk));
2282                         struct xsockbuf_n *xsbrcv = (struct xsockbuf_n *)
2283                             ADVANCE64(xso, sizeof(*xso));
2284                         struct xsockbuf_n *xsbsnd = (struct xsockbuf_n *)
2285                             ADVANCE64(xsbrcv, sizeof(*xsbrcv));
2286                         struct xsockstat_n *xsostats = (struct xsockstat_n *)
2287                             ADVANCE64(xsbsnd, sizeof(*xsbsnd));
2288 
2289                         bzero(buf, item_size);
2290 
2291                         xk->xkp_len = sizeof(struct xkctlpcb);
2292                         xk->xkp_kind = XSO_KCB;
2293                         xk->xkp_unit = kcb->sac.sc_unit;
2294                         xk->xkp_kctpcb = (uint64_t)VM_KERNEL_ADDRPERM(kcb);
2295                         xk->xkp_kctlref = (uint64_t)VM_KERNEL_ADDRPERM(kctl);
2296                         xk->xkp_kctlid = kctl->id;
2297                         strlcpy(xk->xkp_kctlname, kctl->name,
2298                             sizeof(xk->xkp_kctlname));
2299 
2300                         sotoxsocket_n(kcb->so, xso);
2301                         sbtoxsockbuf_n(kcb->so ?
2302                             &kcb->so->so_rcv : NULL, xsbrcv);
2303                         sbtoxsockbuf_n(kcb->so ?
2304                             &kcb->so->so_snd : NULL, xsbsnd);
2305                         sbtoxsockstat_n(kcb->so, xsostats);
2306 
2307                         error = SYSCTL_OUT(req, buf, item_size);
2308 		}
2309 	}
2310 
2311         if (error == 0) {
2312                 /*
2313                  * Give the user an updated idea of our state.
2314                  * If the generation differs from what we told
2315                  * her before, she knows that something happened
2316                  * while we were processing this request, and it
2317                  * might be necessary to retry.
2318                  */
2319                 bzero(&xsg, sizeof(xsg));
2320                 xsg.xg_len = sizeof(xsg);
2321                 xsg.xg_count = n;
2322                 xsg.xg_gen = kctlstat.kcs_gencnt;
2323                 xsg.xg_sogen = so_gencnt;
2324                 error = SYSCTL_OUT(req, &xsg, sizeof(xsg));
2325                 if (error) {
2326                         goto done;
2327 		}
2328 	}
2329 
2330 done:
2331         lck_mtx_unlock(&ctl_mtx);
2332 
2333         kfree_data(buf, item_size);
2334         return error;
2335 }
2336 
2337 int
2338 kctl_getstat SYSCTL_HANDLER_ARGS
2339 {
2340 #pragma unused(oidp, arg1, arg2)
2341         int error = 0;
2342 
2343         lck_mtx_lock(&ctl_mtx);
2344 
2345         if (req->newptr != USER_ADDR_NULL) {
2346                 error = EPERM;
2347                 goto done;
2348 	}
2349         if (req->oldptr == USER_ADDR_NULL) {
2350                 req->oldidx = sizeof(struct kctlstat);
2351                 goto done;
2352 	}
2353 
2354         error = SYSCTL_OUT(req, &kctlstat,
2355             MIN(sizeof(struct kctlstat), req->oldlen));
2356 done:
2357         lck_mtx_unlock(&ctl_mtx);
2358         return error;
2359 }
2360 
2361 void
2362 kctl_fill_socketinfo(struct socket *so, struct socket_info *si)
2363 {
2364         struct ctl_cb *kcb = (struct ctl_cb *)so->so_pcb;
2365         struct kern_ctl_info *kcsi =
2366             &si->soi_proto.pri_kern_ctl;
2367         struct kctl *kctl = kcb->kctl;
2368 
2369         si->soi_kind = SOCKINFO_KERN_CTL;
2370 
2371         if (kctl == 0) {
2372                 return;
2373 	}
2374 
2375         kcsi->kcsi_id = kctl->id;
2376         kcsi->kcsi_reg_unit = kctl->reg_unit;
2377         kcsi->kcsi_flags = kctl->flags;
2378         kcsi->kcsi_recvbufsize = kctl->recvbufsize;
2379         kcsi->kcsi_sendbufsize = kctl->sendbufsize;
2380         kcsi->kcsi_unit = kcb->sac.sc_unit;
2381         strlcpy(kcsi->kcsi_name, kctl->name, MAX_KCTL_NAME);
2382 }
2383