xref: /xnu-12377.41.6/bsd/kern/tty_ptmx.c (revision bbb1b6f9e71b8cdde6e5cd6f4841f207dee3d828)
1 /*
2  * Copyright (c) 1997-2019 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  * Copyright (c) 1982, 1986, 1989, 1993
30  *      The Regents of the University of California.  All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  * 1. Redistributions of source code must retain the above copyright
36  *    notice, this list of conditions and the following disclaimer.
37  * 2. Redistributions in binary form must reproduce the above copyright
38  *    notice, this list of conditions and the following disclaimer in the
39  *    documentation and/or other materials provided with the distribution.
40  * 3. All advertising materials mentioning features or use of this software
41  *    must display the following acknowledgement:
42  *      This product includes software developed by the University of
43  *      California, Berkeley and its contributors.
44  * 4. Neither the name of the University nor the names of its contributors
45  *    may be used to endorse or promote products derived from this software
46  *    without specific prior written permission.
47  *
48  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58  * SUCH DAMAGE.
59  *
60  *	@(#)tty_pty.c	8.4 (Berkeley) 2/20/95
61  */
62 
63 /*
64  * Pseudo-teletype Driver
65  * (Actually two drivers, requiring two entries in 'cdevsw')
66  */
67 #include "pty.h"                /* XXX */
68 
69 #include <sys/param.h>
70 #include <sys/systm.h>
71 #include <sys/ioctl.h>
72 #include <sys/proc_internal.h>
73 #include <sys/kauth.h>
74 #include <sys/tty.h>
75 #include <sys/conf.h>
76 #include <sys/file_internal.h>
77 #include <sys/uio_internal.h>
78 #include <sys/kernel.h>
79 #include <sys/vnode.h>
80 #include <sys/user.h>
81 #include <sys/signalvar.h>
82 #include <sys/sysctl.h>
83 #include <miscfs/devfs/devfs.h>
84 #include <miscfs/devfs/devfsdefs.h>     /* DEVFS_LOCK()/DEVFS_UNLOCK() */
85 #include <libkern/section_keywords.h>
86 
87 #if CONFIG_MACF
88 #include <security/mac_framework.h>
89 #endif
90 
91 #include "tty_dev.h"
92 
93 /*
94  * Forward declarations
95  */
96 int ptmx_init(int n_ptys);
97 static struct ptmx_ioctl *ptmx_get_ioctl(int minor, int open_flag);
98 static int ptmx_free_ioctl(int minor, int open_flag);
99 static int ptmx_get_name(int minor, char *buffer, size_t size);
100 static void ptsd_revoke_knotes(int minor, struct tty *tp);
101 
102 extern  d_open_t        ptsopen;
103 extern  d_close_t       ptsclose;
104 extern  d_read_t        ptsread;
105 extern  d_write_t       ptswrite;
106 extern  d_ioctl_t       ptyioctl;
107 extern  d_stop_t        ptsstop;
108 extern  d_reset_t       ptsreset;
109 extern  d_select_t      ptsselect;
110 
111 extern  d_open_t        ptcopen;
112 extern  d_close_t       ptcclose;
113 extern  d_read_t        ptcread;
114 extern  d_write_t       ptcwrite;
115 extern  d_stop_t        ptcstop;
116 extern  d_reset_t       ptcreset;
117 extern  d_select_t      ptcselect;
118 
119 static int ptmx_major;          /* dynamically assigned major number */
120 static const struct cdevsw ptmx_cdev = {
121 	.d_open       = ptcopen,
122 	.d_close      = ptcclose,
123 	.d_read       = ptcread,
124 	.d_write      = ptcwrite,
125 	.d_ioctl      = ptyioctl,
126 	.d_stop       = ptcstop,
127 	.d_reset      = ptcreset,
128 	.d_ttys       = NULL,
129 	.d_select     = ptcselect,
130 	.d_mmap       = eno_mmap,
131 	.d_strategy   = eno_strat,
132 	.d_reserved_1 = eno_getc,
133 	.d_reserved_2 = eno_putc,
134 	.d_type       = D_TTY
135 };
136 
137 static int ptsd_major;          /* dynamically assigned major number */
138 static const struct cdevsw ptsd_cdev = {
139 	.d_open       = ptsopen,
140 	.d_close      = ptsclose,
141 	.d_read       = ptsread,
142 	.d_write      = ptswrite,
143 	.d_ioctl      = ptyioctl,
144 	.d_stop       = ptsstop,
145 	.d_reset      = ptsreset,
146 	.d_ttys       = NULL,
147 	.d_select     = ptsselect,
148 	.d_mmap       = eno_mmap,
149 	.d_strategy   = eno_strat,
150 	.d_reserved_1 = eno_getc,
151 	.d_reserved_2 = eno_putc,
152 	.d_type       = D_TTY
153 };
154 
155 /*
156  * ptmx == /dev/ptmx
157  * ptsd == /dev/pts[0123456789]{3}
158  */
159 #define PTMX_TEMPLATE   "ptmx"
160 #define PTSD_TEMPLATE   "ttys%03d"
161 
162 /*
163  * System-wide limit on the max number of cloned ptys
164  */
165 #define PTMX_MAX_DEFAULT        511     /* 512 entries */
166 #define PTMX_MAX_HARD           999     /* 1000 entries, due to PTSD_TEMPLATE */
167 
168 static int ptmx_max = PTMX_MAX_DEFAULT; /* default # of clones we allow */
169 
170 /* Range enforcement for the sysctl */
171 static int
sysctl_ptmx_max(__unused struct sysctl_oid * oidp,__unused void * arg1,__unused int arg2,struct sysctl_req * req)172 sysctl_ptmx_max(__unused struct sysctl_oid *oidp, __unused void *arg1,
173     __unused int arg2, struct sysctl_req *req)
174 {
175 	int new_value, changed;
176 	int error = sysctl_io_number(req, ptmx_max, sizeof(int), &new_value, &changed);
177 	if (changed) {
178 		if (new_value > 0 && new_value <= PTMX_MAX_HARD) {
179 			ptmx_max = new_value;
180 		} else {
181 			error = EINVAL;
182 		}
183 	}
184 	return error;
185 }
186 
187 SYSCTL_NODE(_kern, KERN_TTY, tty, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "TTY");
188 SYSCTL_PROC(_kern_tty, OID_AUTO, ptmx_max,
189     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
190     &ptmx_max, 0, &sysctl_ptmx_max, "I", "ptmx_max");
191 
192 static int      ptmx_clone(dev_t dev, int minor);
193 
194 static struct tty_dev_t _ptmx_driver;
195 
196 int
ptmx_init(__unused int config_count)197 ptmx_init( __unused int config_count)
198 {
199 	/*
200 	 * We start looking at slot 10, since there are inits that will
201 	 * stomp explicit slots (e.g. vndevice stomps 1) below that.
202 	 */
203 
204 	/* Get a major number for /dev/ptmx */
205 	if ((ptmx_major = cdevsw_add(-15, &ptmx_cdev)) == -1) {
206 		printf("ptmx_init: failed to obtain /dev/ptmx major number\n");
207 		return ENOENT;
208 	}
209 
210 	if (cdevsw_setkqueueok(ptmx_major, &ptmx_cdev, CDEVSW_IS_PTC) == -1) {
211 		panic("Failed to set flags on ptmx cdevsw entry.");
212 	}
213 
214 	/* Get a major number for /dev/pts/nnn */
215 	if ((ptsd_major = cdevsw_add(-15, &ptsd_cdev)) == -1) {
216 		(void)cdevsw_remove(ptmx_major, &ptmx_cdev);
217 		printf("ptmx_init: failed to obtain /dev/ptmx major number\n");
218 		return ENOENT;
219 	}
220 
221 	if (cdevsw_setkqueueok(ptsd_major, &ptsd_cdev, CDEVSW_IS_PTS) == -1) {
222 		panic("Failed to set flags on ptmx cdevsw entry.");
223 	}
224 
225 	/* Create the /dev/ptmx device {<major>,0} */
226 	(void)devfs_make_node_clone(makedev(ptmx_major, 0),
227 	    DEVFS_CHAR, UID_ROOT, GID_TTY, 0666,
228 	    ptmx_clone, PTMX_TEMPLATE);
229 
230 	_ptmx_driver.primary = ptmx_major;
231 	_ptmx_driver.replica = ptsd_major;
232 	_ptmx_driver.fix_7828447 = 1;
233 	_ptmx_driver.fix_7070978 = 1;
234 #if CONFIG_MACF
235 	_ptmx_driver.mac_notify = 1;
236 #endif
237 	_ptmx_driver.open = &ptmx_get_ioctl;
238 	_ptmx_driver.free = &ptmx_free_ioctl;
239 	_ptmx_driver.name = &ptmx_get_name;
240 	_ptmx_driver.revoke = &ptsd_revoke_knotes;
241 	tty_dev_register(&_ptmx_driver);
242 
243 	return 0;
244 }
245 
246 
247 static struct _ptmx_ioctl_state {
248 	struct ptmx_ioctl       **pis_ioctl_list;       /* pointer vector */
249 	int                     pis_total;              /* total slots */
250 	int                     pis_free;               /* free slots */
251 } _state;
252 #define PTMX_GROW_VECTOR        16      /* Grow by this many slots at a time */
253 
254 /*
255  * Given a minor number, return the corresponding structure for that minor
256  * number.  If there isn't one, and the create flag is specified, we create
257  * one if possible.
258  *
259  * Parameters:	minor			Minor number of ptmx device
260  *		open_flag		PF_OPEN_M	First open of primary
261  *					PF_OPEN_S	First open of replica
262  *					0		Just want ioctl struct
263  *
264  * Returns:	NULL			Did not exist/could not create
265  *		!NULL			structure corresponding minor number
266  *
267  * Locks:	tty_lock() on ptmx_ioctl->pt_tty NOT held on entry or exit.
268  */
269 static struct ptmx_ioctl *
ptmx_get_ioctl(int minor,int open_flag)270 ptmx_get_ioctl(int minor, int open_flag)
271 {
272 	struct ptmx_ioctl *ptmx_ioctl = NULL;
273 
274 	if (open_flag & PF_OPEN_M) {
275 		struct ptmx_ioctl *new_ptmx_ioctl;
276 
277 		DEVFS_LOCK();
278 		/*
279 		 * If we are about to allocate more memory, but we have
280 		 * already hit the administrative limit, then fail the
281 		 * operation.
282 		 *
283 		 * Note:	Subtract free from total when making this
284 		 *		check to allow unit increments, rather than
285 		 *		snapping to the nearest PTMX_GROW_VECTOR...
286 		 */
287 		if ((_state.pis_total - _state.pis_free) >= ptmx_max) {
288 			DEVFS_UNLOCK();
289 			printf("ptmx_get_ioctl failed due to ptmx_max limit %d\n", ptmx_max);
290 			return NULL;
291 		}
292 		DEVFS_UNLOCK();
293 
294 		new_ptmx_ioctl = kalloc_type(struct ptmx_ioctl,
295 		    Z_WAITOK | Z_ZERO | Z_NOFAIL);
296 
297 		if ((new_ptmx_ioctl->pt_tty = ttymalloc()) == NULL) {
298 			kfree_type(struct ptmx_ioctl, new_ptmx_ioctl);
299 			return NULL;
300 		}
301 
302 		/*
303 		 * Hold the DEVFS_LOCK() over this whole operation; devfs
304 		 * itself does this over malloc/free as well, so this should
305 		 * be safe to do.  We hold it longer than we want to, but
306 		 * doing so avoids a reallocation race on the minor number.
307 		 */
308 		DEVFS_LOCK();
309 
310 		/*
311 		 * Check again to ensure the limit is not reached after initial check
312 		 * when the lock was dropped momentarily for malloc.
313 		 */
314 		if ((_state.pis_total - _state.pis_free) >= ptmx_max) {
315 			ttyfree(new_ptmx_ioctl->pt_tty);
316 			DEVFS_UNLOCK();
317 			kfree_type(struct ptmx_ioctl, new_ptmx_ioctl);
318 			printf("ptmx_get_ioctl failed due to ptmx_max limit %d\n", ptmx_max);
319 			return NULL;
320 		}
321 
322 		/* Need to allocate a larger vector? */
323 		if (_state.pis_free == 0) {
324 			struct ptmx_ioctl **new_pis_ioctl_list;
325 			struct ptmx_ioctl **old_pis_ioctl_list = NULL;
326 			size_t old_pis_total = 0;
327 
328 			/* Yes. */
329 			new_pis_ioctl_list = kalloc_type(struct ptmx_ioctl *,
330 			    _state.pis_total + PTMX_GROW_VECTOR, Z_WAITOK | Z_ZERO);
331 			if (new_pis_ioctl_list == NULL) {
332 				ttyfree(new_ptmx_ioctl->pt_tty);
333 				DEVFS_UNLOCK();
334 				kfree_type(struct ptmx_ioctl, new_ptmx_ioctl);
335 				return NULL;
336 			}
337 
338 			/* If this is not the first time, copy the old over */
339 			bcopy(_state.pis_ioctl_list, new_pis_ioctl_list, sizeof(struct ptmx_ioctl *) * _state.pis_total);
340 			old_pis_ioctl_list = _state.pis_ioctl_list;
341 			old_pis_total = _state.pis_total;
342 			_state.pis_ioctl_list = new_pis_ioctl_list;
343 			_state.pis_free += PTMX_GROW_VECTOR;
344 			_state.pis_total += PTMX_GROW_VECTOR;
345 			kfree_type(struct ptmx_ioctl *, old_pis_total, old_pis_ioctl_list);
346 		}
347 
348 		/* is minor in range now? */
349 		if (minor < 0 || minor >= _state.pis_total) {
350 			ttyfree(new_ptmx_ioctl->pt_tty);
351 			DEVFS_UNLOCK();
352 			kfree_type(struct ptmx_ioctl, new_ptmx_ioctl);
353 			printf("ptmx_get_ioctl failed because minor number %d was out of range\n", minor);
354 			return NULL;
355 		}
356 
357 		if (_state.pis_ioctl_list[minor] != NULL) {
358 			ttyfree(new_ptmx_ioctl->pt_tty);
359 			DEVFS_UNLOCK();
360 			kfree_type(struct ptmx_ioctl, new_ptmx_ioctl);
361 
362 			/* Special error value so we know to redrive the open, we've been raced */
363 			/* XXX Can this still occur? */
364 			return (struct ptmx_ioctl*)-1;
365 		}
366 
367 		/* Vector is large enough; grab a new ptmx_ioctl */
368 
369 		/* Now grab a free slot... */
370 		_state.pis_ioctl_list[minor] = new_ptmx_ioctl;
371 
372 		/* reduce free count */
373 		_state.pis_free--;
374 
375 		_state.pis_ioctl_list[minor]->pt_flags |= PF_OPEN_M;
376 		DEVFS_UNLOCK();
377 
378 		/* Create the /dev/ttysXXX device {<major>,XXX} */
379 		new_ptmx_ioctl->pt_devhandle = devfs_make_node(
380 			makedev(ptsd_major, minor),
381 			DEVFS_CHAR, UID_ROOT, GID_TTY, 0620,
382 			PTSD_TEMPLATE, minor);
383 		if (new_ptmx_ioctl->pt_devhandle == NULL) {
384 			printf("devfs_make_node() call failed for ptmx_get_ioctl()!!!!\n");
385 		}
386 	}
387 
388 	/*
389 	 * Lock is held here to protect race when the 'pis_ioctl_list' array is
390 	 * being reallocated to increase its slots.
391 	 */
392 	DEVFS_LOCK();
393 	if (minor >= 0 && minor < _state.pis_total) {
394 		ptmx_ioctl = _state.pis_ioctl_list[minor];
395 		if (ptmx_ioctl && (open_flag & PF_OPEN_S)) {
396 			ptmx_ioctl->pt_flags |= PF_OPEN_S;
397 		}
398 	}
399 	DEVFS_UNLOCK();
400 
401 	return ptmx_ioctl;
402 }
403 
404 /*
405  * Locks:	tty_lock() of old_ptmx_ioctl->pt_tty NOT held for this call.
406  */
407 static int
ptmx_free_ioctl(int minor,int open_flag)408 ptmx_free_ioctl(int minor, int open_flag)
409 {
410 	struct ptmx_ioctl *old_ptmx_ioctl = NULL;
411 
412 	DEVFS_LOCK();
413 
414 	if (minor < 0 || minor >= _state.pis_total) {
415 		DEVFS_UNLOCK();
416 		return -1;
417 	}
418 
419 	_state.pis_ioctl_list[minor]->pt_flags &= ~(open_flag);
420 
421 	/*
422 	 * Was this the last close?  We will recognize it because we only get
423 	 * a notification on the last close of a device, and we will have
424 	 * cleared both the primary and the replica open bits in the flags.
425 	 */
426 	if (!(_state.pis_ioctl_list[minor]->pt_flags & (PF_OPEN_M | PF_OPEN_S))) {
427 		/* Mark as free so it can be reallocated later */
428 		old_ptmx_ioctl = _state.pis_ioctl_list[minor];
429 		_state.pis_ioctl_list[minor] = NULL;
430 		_state.pis_free++;
431 	}
432 	DEVFS_UNLOCK();
433 
434 	/* Free old after dropping lock */
435 	if (old_ptmx_ioctl != NULL) {
436 		/*
437 		 * XXX See <rdar://5348651> and <rdar://4854638>
438 		 *
439 		 * XXX Conditional to be removed when/if tty/pty reference
440 		 * XXX counting and mutex implemented.
441 		 */
442 		if (old_ptmx_ioctl->pt_devhandle != NULL) {
443 			devfs_remove(old_ptmx_ioctl->pt_devhandle);
444 		}
445 		ttyfree(old_ptmx_ioctl->pt_tty);
446 		kfree_type(struct ptmx_ioctl, old_ptmx_ioctl);
447 	}
448 
449 	return 0;     /* Success */
450 }
451 
452 static int
ptmx_get_name(int minor,char * buffer,size_t size)453 ptmx_get_name(int minor, char *buffer, size_t size)
454 {
455 	return snprintf(buffer, size, "/dev/" PTSD_TEMPLATE, minor);
456 }
457 
458 
459 
460 /*
461  * Given the dev entry that's being opened, we clone the device.  This driver
462  * doesn't actually use the dev entry, since we alreaqdy know who we are by
463  * being called from this code.  This routine is a callback registered from
464  * devfs_make_node_clone() in ptmx_init(); it's purpose is to provide a new
465  * minor number, or to return -1, if one can't be provided.
466  *
467  * Parameters:	dev			The device we are cloning from
468  *
469  * Returns:	>= 0			A new minor device number
470  *		-1			Error: ENOMEM ("Can't alloc device")
471  *
472  * NOTE:	Called with DEVFS_LOCK() held
473  */
474 static int
ptmx_clone(__unused dev_t dev,int action)475 ptmx_clone(__unused dev_t dev, int action)
476 {
477 	int i;
478 
479 	if (action == DEVFS_CLONE_ALLOC) {
480 		/* First one */
481 		if (_state.pis_total == 0) {
482 			return 0;
483 		}
484 
485 		/*
486 		 * Note: We can add hinting on free slots, if this linear search
487 		 * ends up being a performance bottleneck...
488 		 */
489 		for (i = 0; i < _state.pis_total; i++) {
490 			if (_state.pis_ioctl_list[i] == NULL) {
491 				break;
492 			}
493 		}
494 
495 		/*
496 		 * XXX We fall off the end here; if we did this twice at the
497 		 * XXX same time, we could return the same minor to two
498 		 * XXX callers; we should probably exand the pointer vector
499 		 * XXX here, but I need more information on the MALLOC/FREE
500 		 * XXX locking to ensure against a deadlock.  Maybe we can
501 		 * XXX just high watermark it at 1/2 of PTMX_GROW_VECTOR?
502 		 * XXX That would require returning &minor as implict return
503 		 * XXX and an error code ("EAGAIN/ERESTART") or 0 as our
504 		 * XXX explicit return.
505 		 */
506 
507 		return i;     /* empty slot or next slot */
508 	}
509 	return -1;
510 }
511 
512 
513 /*
514  * kqueue support.
515  */
516 int ptsd_kqfilter(dev_t dev, struct knote *kn);
517 static void ptsd_kqops_detach(struct knote *);
518 static int ptsd_kqops_event(struct knote *, long);
519 static int ptsd_kqops_touch(struct knote *kn, struct kevent_qos_s *kev);
520 static int ptsd_kqops_process(struct knote *kn, struct kevent_qos_s *kev);
521 
522 SECURITY_READ_ONLY_EARLY(struct filterops) ptsd_kqops = {
523 	.f_isfd = 1,
524 	/* attach is handled by ptsd_kqfilter -- the dev node must be passed in */
525 	.f_detach = ptsd_kqops_detach,
526 	.f_event = ptsd_kqops_event,
527 	.f_touch = ptsd_kqops_touch,
528 	.f_process = ptsd_kqops_process,
529 };
530 
531 /*
532  * In the normal case, by the time the driver_close() routine is called
533  * on the replica, all knotes have been detached.  However in the revoke(2)
534  * case, the driver's close routine is called while there are knotes active
535  * that reference the handlers below.  And we have no obvious means to
536  * reach from the driver out to the kqueue's that reference them to get
537  * them to stop.
538  */
539 
540 static void
ptsd_kqops_detach(struct knote * kn)541 ptsd_kqops_detach(struct knote *kn)
542 {
543 	struct tty *tp = knote_kn_hook_get_raw(kn);
544 	tty_lock(tp);
545 
546 	if (!KNOTE_IS_AUTODETACHED(kn)) {
547 		/*
548 		 * If we got here, it must be due to the fact that we are referencing an open
549 		 * tty - ttyclose always autodetaches knotes under the tty lock and marks
550 		 * the state as closed
551 		 */
552 		assert(tp->t_state & TS_ISOPEN);
553 
554 		switch (kn->kn_filter) {
555 		case EVFILT_READ:
556 			KNOTE_DETACH(&tp->t_rsel.si_note, kn);
557 			break;
558 		case EVFILT_WRITE:
559 			KNOTE_DETACH(&tp->t_wsel.si_note, kn);
560 			break;
561 		default:
562 			panic("invalid knote %p detach, filter: %d", kn, kn->kn_filter);
563 			break;
564 		}
565 	}
566 
567 	knote_kn_hook_set_raw(kn, NULL);
568 
569 	tty_unlock(tp);
570 	ttyfree(tp);
571 }
572 
573 static int
ptsd_kqops_common(struct knote * kn,struct kevent_qos_s * kev,struct tty * tp)574 ptsd_kqops_common(struct knote *kn, struct kevent_qos_s *kev, struct tty *tp)
575 {
576 	int retval = 0;
577 	int64_t data = 0;
578 
579 	TTY_LOCK_OWNED(tp);
580 
581 	switch (kn->kn_filter) {
582 	case EVFILT_READ:
583 		/*
584 		 * ttnread can change the tty state,
585 		 * hence must be done upfront, before any other check.
586 		 */
587 		data = ttnread(tp);
588 		retval = (data > 0);
589 		break;
590 
591 	case EVFILT_WRITE:
592 		if ((tp->t_outq.c_cc <= tp->t_lowat) &&
593 		    (tp->t_state & TS_CONNECTED)) {
594 			data = tp->t_outq.c_cn - tp->t_outq.c_cc;
595 			retval = 1;
596 		}
597 		break;
598 
599 	default:
600 		panic("ptsd kevent: unexpected filter: %d, kn = %p, tty = %p",
601 		    kn->kn_filter, kn, tp);
602 		break;
603 	}
604 
605 	if (tp->t_state & TS_ZOMBIE) {
606 		kn->kn_flags |= EV_EOF;
607 	}
608 	if (kn->kn_flags & EV_EOF) {
609 		retval = 1;
610 	}
611 	if (retval && kev) {
612 		knote_fill_kevent(kn, kev, data);
613 	}
614 	return retval;
615 }
616 
617 static int
ptsd_kqops_event(struct knote * kn,long hint)618 ptsd_kqops_event(struct knote *kn, long hint)
619 {
620 	struct tty *tp = knote_kn_hook_get_raw(kn);
621 	int ret;
622 
623 	TTY_LOCK_OWNED(tp);
624 
625 	if (hint & NOTE_REVOKE) {
626 		kn->kn_flags |= EV_EOF | EV_ONESHOT;
627 		ret = 1;
628 	} else {
629 		ret = ptsd_kqops_common(kn, NULL, tp);
630 	}
631 
632 	return ret;
633 }
634 
635 static int
ptsd_kqops_touch(struct knote * kn,struct kevent_qos_s * kev)636 ptsd_kqops_touch(struct knote *kn, struct kevent_qos_s *kev)
637 {
638 	struct tty *tp = knote_kn_hook_get_raw(kn);
639 	int ret;
640 
641 	tty_lock(tp);
642 
643 	/* accept new kevent state */
644 	kn->kn_sfflags = kev->fflags;
645 	kn->kn_sdata = kev->data;
646 
647 	/* recapture fired state of knote */
648 	ret = ptsd_kqops_common(kn, NULL, tp);
649 
650 	tty_unlock(tp);
651 
652 	return ret;
653 }
654 
655 static int
ptsd_kqops_process(struct knote * kn,struct kevent_qos_s * kev)656 ptsd_kqops_process(struct knote *kn, struct kevent_qos_s *kev)
657 {
658 	struct tty *tp = knote_kn_hook_get_raw(kn);
659 	int ret;
660 
661 	tty_lock(tp);
662 	ret = ptsd_kqops_common(kn, kev, tp);
663 	tty_unlock(tp);
664 
665 	return ret;
666 }
667 
668 int
ptsd_kqfilter(dev_t dev,struct knote * kn)669 ptsd_kqfilter(dev_t dev, struct knote *kn)
670 {
671 	struct tty *tp = NULL;
672 	struct ptmx_ioctl *pti = NULL;
673 	int ret;
674 
675 	/* make sure we're talking about the right device type */
676 	if (cdevsw[major(dev)].d_open != ptsopen) {
677 		knote_set_error(kn, ENODEV);
678 		return 0;
679 	}
680 
681 	if ((pti = ptmx_get_ioctl(minor(dev), 0)) == NULL) {
682 		knote_set_error(kn, ENXIO);
683 		return 0;
684 	}
685 
686 	tp = pti->pt_tty;
687 	tty_lock(tp);
688 
689 	assert(tp->t_state & TS_ISOPEN);
690 
691 	kn->kn_filtid = EVFILTID_PTSD;
692 	/* the tty will be freed when detaching the knote */
693 	ttyhold(tp);
694 	knote_kn_hook_set_raw(kn, tp);
695 
696 	switch (kn->kn_filter) {
697 	case EVFILT_READ:
698 		KNOTE_ATTACH(&tp->t_rsel.si_note, kn);
699 		break;
700 	case EVFILT_WRITE:
701 		KNOTE_ATTACH(&tp->t_wsel.si_note, kn);
702 		break;
703 	default:
704 		panic("ptsd kevent: unexpected filter: %d, kn = %p, tty = %p",
705 		    kn->kn_filter, kn, tp);
706 		break;
707 	}
708 
709 	/* capture current event state */
710 	ret = ptsd_kqops_common(kn, NULL, tp);
711 
712 	tty_unlock(tp);
713 
714 	return ret;
715 }
716 
717 /*
718  * Support for revoke(2).
719  */
720 static void
ptsd_revoke_knotes(__unused int minor,struct tty * tp)721 ptsd_revoke_knotes(__unused int minor, struct tty *tp)
722 {
723 	tty_lock(tp);
724 
725 	ttwakeup(tp);
726 	assert((tp->t_rsel.si_flags & SI_KNPOSTING) == 0);
727 	knote(&tp->t_rsel.si_note, NOTE_REVOKE, true);
728 
729 	ttwwakeup(tp);
730 	assert((tp->t_wsel.si_flags & SI_KNPOSTING) == 0);
731 	knote(&tp->t_wsel.si_note, NOTE_REVOKE, true);
732 
733 	tty_unlock(tp);
734 }
735 
736 /*
737  * kevent filter routines for the master side of a pty, a ptmx.
738  *
739  * Stuff the ptmx_ioctl structure into the hook for ptmx knotes.  Use the
740  * embedded tty's lock for synchronization.
741  */
742 
743 int ptmx_kqfilter(dev_t dev, struct knote *kn);
744 static void ptmx_kqops_detach(struct knote *);
745 static int ptmx_kqops_event(struct knote *, long);
746 static int ptmx_kqops_touch(struct knote *kn, struct kevent_qos_s *kev);
747 static int ptmx_kqops_process(struct knote *kn, struct kevent_qos_s *kev);
748 static int ptmx_kqops_common(struct knote *kn, struct kevent_qos_s *kev,
749     struct ptmx_ioctl *pti, struct tty *tp);
750 
751 SECURITY_READ_ONLY_EARLY(struct filterops) ptmx_kqops = {
752 	.f_isfd = 1,
753 	/* attach is handled by ptmx_kqfilter -- the dev node must be passed in */
754 	.f_detach = ptmx_kqops_detach,
755 	.f_event = ptmx_kqops_event,
756 	.f_touch = ptmx_kqops_touch,
757 	.f_process = ptmx_kqops_process,
758 };
759 
760 static struct ptmx_ioctl *
ptmx_knote_ioctl(struct knote * kn)761 ptmx_knote_ioctl(struct knote *kn)
762 {
763 	return (struct ptmx_ioctl *)knote_kn_hook_get_raw(kn);
764 }
765 
766 static struct tty *
ptmx_knote_tty(struct knote * kn)767 ptmx_knote_tty(struct knote *kn)
768 {
769 	return ptmx_knote_ioctl(kn)->pt_tty;
770 }
771 
772 int
ptmx_kqfilter(dev_t dev,struct knote * kn)773 ptmx_kqfilter(dev_t dev, struct knote *kn)
774 {
775 	struct tty *tp = NULL;
776 	struct ptmx_ioctl *pti = NULL;
777 	int ret;
778 
779 	/* make sure we're talking about the right device type */
780 	if (cdevsw[major(dev)].d_open != ptcopen) {
781 		knote_set_error(kn, ENODEV);
782 		return 0;
783 	}
784 
785 	if ((pti = ptmx_get_ioctl(minor(dev), 0)) == NULL) {
786 		knote_set_error(kn, ENXIO);
787 		return 0;
788 	}
789 
790 	tp = pti->pt_tty;
791 	tty_lock(tp);
792 
793 	kn->kn_filtid = EVFILTID_PTMX;
794 	/* the tty will be freed when detaching the knote */
795 	ttyhold(tp);
796 	knote_kn_hook_set_raw(kn, pti);
797 
798 	/*
799 	 * Attach to the ptmx's selinfo structures.  This is the major difference
800 	 * to the ptsd filtops, which use the selinfo structures in the tty
801 	 * structure.
802 	 */
803 	switch (kn->kn_filter) {
804 	case EVFILT_READ:
805 		KNOTE_ATTACH(&pti->pt_selr.si_note, kn);
806 		break;
807 	case EVFILT_WRITE:
808 		KNOTE_ATTACH(&pti->pt_selw.si_note, kn);
809 		break;
810 	default:
811 		panic("ptmx kevent: unexpected filter: %d, kn = %p, tty = %p",
812 		    kn->kn_filter, kn, tp);
813 		break;
814 	}
815 
816 	/* capture current event state */
817 	ret = ptmx_kqops_common(kn, NULL, pti, tp);
818 
819 	tty_unlock(tp);
820 
821 	return ret;
822 }
823 
824 static void
ptmx_kqops_detach(struct knote * kn)825 ptmx_kqops_detach(struct knote *kn)
826 {
827 	struct ptmx_ioctl *pti = knote_kn_hook_get_raw(kn);
828 	struct tty *tp = pti->pt_tty;
829 
830 	tty_lock(tp);
831 
832 	if (!KNOTE_IS_AUTODETACHED(kn)) {
833 		switch (kn->kn_filter) {
834 		case EVFILT_READ:
835 			KNOTE_DETACH(&pti->pt_selr.si_note, kn);
836 			break;
837 		case EVFILT_WRITE:
838 			KNOTE_DETACH(&pti->pt_selw.si_note, kn);
839 			break;
840 		default:
841 			panic("invalid knote %p detach, filter: %d", kn, kn->kn_filter);
842 			break;
843 		}
844 	}
845 
846 	knote_kn_hook_set_raw(kn, NULL);
847 
848 	tty_unlock(tp);
849 	ttyfree(tp);
850 }
851 
852 static int
ptmx_kqops_common(struct knote * kn,struct kevent_qos_s * kev,struct ptmx_ioctl * pti,struct tty * tp)853 ptmx_kqops_common(struct knote *kn, struct kevent_qos_s *kev,
854     struct ptmx_ioctl *pti, struct tty *tp)
855 {
856 	int retval = 0;
857 	int64_t data = 0;
858 
859 	TTY_LOCK_OWNED(tp);
860 
861 	switch (kn->kn_filter) {
862 	case EVFILT_READ:
863 		/* there's data on the TTY and it's not stopped */
864 		if (tp->t_outq.c_cc && !(tp->t_state & TS_TTSTOP)) {
865 			data = tp->t_outq.c_cc;
866 			retval = data > 0;
867 		} else if (((pti->pt_flags & PF_PKT) && pti->pt_send) ||
868 		    ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl)) {
869 			retval = 1;
870 		}
871 		break;
872 
873 	case EVFILT_WRITE:
874 		retval = (TTYHOG - 2) - (tp->t_rawq.c_cc + tp->t_canq.c_cc);
875 		if (tp->t_canq.c_cc == 0 && (tp->t_lflag & ICANON)) {
876 			retval = 1;
877 		}
878 		if (retval < 0) {
879 			retval = 0;
880 		}
881 		break;
882 
883 	default:
884 		panic("ptmx kevent: unexpected filter: %d, kn = %p, tty = %p",
885 		    kn->kn_filter, kn, tp);
886 		break;
887 	}
888 
889 	/* disconnects should force a wakeup (EOF) */
890 	if (!(tp->t_state & TS_CONNECTED) || (tp->t_state & TS_ZOMBIE)) {
891 		kn->kn_flags |= EV_EOF;
892 	}
893 	if (kn->kn_flags & EV_EOF) {
894 		retval = 1;
895 	}
896 	if (retval && kev) {
897 		knote_fill_kevent(kn, kev, data);
898 	}
899 	return retval;
900 }
901 
902 static int
ptmx_kqops_event(struct knote * kn,long hint)903 ptmx_kqops_event(struct knote *kn, long hint)
904 {
905 	struct ptmx_ioctl *pti = ptmx_knote_ioctl(kn);
906 	struct tty *tp = ptmx_knote_tty(kn);
907 	int ret;
908 
909 	TTY_LOCK_OWNED(tp);
910 
911 	if (hint & NOTE_REVOKE) {
912 		kn->kn_flags |= EV_EOF | EV_ONESHOT;
913 		ret = 1;
914 	} else {
915 		ret = ptmx_kqops_common(kn, NULL, pti, tp);
916 	}
917 
918 	return ret;
919 }
920 
921 static int
ptmx_kqops_touch(struct knote * kn,struct kevent_qos_s * kev)922 ptmx_kqops_touch(struct knote *kn, struct kevent_qos_s *kev)
923 {
924 	struct ptmx_ioctl *pti = ptmx_knote_ioctl(kn);
925 	struct tty *tp = ptmx_knote_tty(kn);
926 	int ret;
927 
928 	tty_lock(tp);
929 
930 	/* accept new kevent state */
931 	kn->kn_sfflags = kev->fflags;
932 	kn->kn_sdata = kev->data;
933 
934 	/* recapture fired state of knote */
935 	ret = ptmx_kqops_common(kn, NULL, pti, tp);
936 
937 	tty_unlock(tp);
938 
939 	return ret;
940 }
941 
942 static int
ptmx_kqops_process(struct knote * kn,struct kevent_qos_s * kev)943 ptmx_kqops_process(struct knote *kn, struct kevent_qos_s *kev)
944 {
945 	struct ptmx_ioctl *pti = ptmx_knote_ioctl(kn);
946 	struct tty *tp = ptmx_knote_tty(kn);
947 	int ret;
948 
949 	tty_lock(tp);
950 	ret = ptmx_kqops_common(kn, kev, pti, tp);
951 	tty_unlock(tp);
952 
953 	return ret;
954 }
955