xref: /xnu-10002.61.3/bsd/kern/tty_ptmx.c (revision 0f4c859e951fba394238ab619495c4e1d54d0f34)
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 			return NULL;
290 		}
291 		DEVFS_UNLOCK();
292 
293 		new_ptmx_ioctl = kalloc_type(struct ptmx_ioctl,
294 		    Z_WAITOK | Z_ZERO | Z_NOFAIL);
295 
296 		if ((new_ptmx_ioctl->pt_tty = ttymalloc()) == NULL) {
297 			kfree_type(struct ptmx_ioctl, new_ptmx_ioctl);
298 			return NULL;
299 		}
300 
301 		/*
302 		 * Hold the DEVFS_LOCK() over this whole operation; devfs
303 		 * itself does this over malloc/free as well, so this should
304 		 * be safe to do.  We hold it longer than we want to, but
305 		 * doing so avoids a reallocation race on the minor number.
306 		 */
307 		DEVFS_LOCK();
308 
309 		/*
310 		 * Check again to ensure the limit is not reached after initial check
311 		 * when the lock was dropped momentarily for malloc.
312 		 */
313 		if ((_state.pis_total - _state.pis_free) >= ptmx_max) {
314 			ttyfree(new_ptmx_ioctl->pt_tty);
315 			DEVFS_UNLOCK();
316 			kfree_type(struct ptmx_ioctl, new_ptmx_ioctl);
317 			return NULL;
318 		}
319 
320 		/* Need to allocate a larger vector? */
321 		if (_state.pis_free == 0) {
322 			struct ptmx_ioctl **new_pis_ioctl_list;
323 			struct ptmx_ioctl **old_pis_ioctl_list = NULL;
324 			size_t old_pis_total = 0;
325 
326 			/* Yes. */
327 			new_pis_ioctl_list = kalloc_type(struct ptmx_ioctl *,
328 			    _state.pis_total + PTMX_GROW_VECTOR, Z_WAITOK | Z_ZERO);
329 			if (new_pis_ioctl_list == NULL) {
330 				ttyfree(new_ptmx_ioctl->pt_tty);
331 				DEVFS_UNLOCK();
332 				kfree_type(struct ptmx_ioctl, new_ptmx_ioctl);
333 				return NULL;
334 			}
335 
336 			/* If this is not the first time, copy the old over */
337 			bcopy(_state.pis_ioctl_list, new_pis_ioctl_list, sizeof(struct ptmx_ioctl *) * _state.pis_total);
338 			old_pis_ioctl_list = _state.pis_ioctl_list;
339 			old_pis_total = _state.pis_total;
340 			_state.pis_ioctl_list = new_pis_ioctl_list;
341 			_state.pis_free += PTMX_GROW_VECTOR;
342 			_state.pis_total += PTMX_GROW_VECTOR;
343 			kfree_type(struct ptmx_ioctl *, old_pis_total, old_pis_ioctl_list);
344 		}
345 
346 		/* is minor in range now? */
347 		if (minor < 0 || minor >= _state.pis_total) {
348 			ttyfree(new_ptmx_ioctl->pt_tty);
349 			DEVFS_UNLOCK();
350 			kfree_type(struct ptmx_ioctl, new_ptmx_ioctl);
351 			return NULL;
352 		}
353 
354 		if (_state.pis_ioctl_list[minor] != NULL) {
355 			ttyfree(new_ptmx_ioctl->pt_tty);
356 			DEVFS_UNLOCK();
357 			kfree_type(struct ptmx_ioctl, new_ptmx_ioctl);
358 
359 			/* Special error value so we know to redrive the open, we've been raced */
360 			return (struct ptmx_ioctl*)-1;
361 		}
362 
363 		/* Vector is large enough; grab a new ptmx_ioctl */
364 
365 		/* Now grab a free slot... */
366 		_state.pis_ioctl_list[minor] = new_ptmx_ioctl;
367 
368 		/* reduce free count */
369 		_state.pis_free--;
370 
371 		_state.pis_ioctl_list[minor]->pt_flags |= PF_OPEN_M;
372 		DEVFS_UNLOCK();
373 
374 		/* Create the /dev/ttysXXX device {<major>,XXX} */
375 		_state.pis_ioctl_list[minor]->pt_devhandle = devfs_make_node(
376 			makedev(ptsd_major, minor),
377 			DEVFS_CHAR, UID_ROOT, GID_TTY, 0620,
378 			PTSD_TEMPLATE, minor);
379 		if (_state.pis_ioctl_list[minor]->pt_devhandle == NULL) {
380 			printf("devfs_make_node() call failed for ptmx_get_ioctl()!!!!\n");
381 		}
382 	}
383 
384 	/*
385 	 * Lock is held here to protect race when the 'pis_ioctl_list' array is
386 	 * being reallocated to increase its slots.
387 	 */
388 	DEVFS_LOCK();
389 	if (minor >= 0 && minor < _state.pis_total) {
390 		ptmx_ioctl = _state.pis_ioctl_list[minor];
391 		if (ptmx_ioctl && (open_flag & PF_OPEN_S)) {
392 			ptmx_ioctl->pt_flags |= PF_OPEN_S;
393 		}
394 	}
395 	DEVFS_UNLOCK();
396 
397 	return ptmx_ioctl;
398 }
399 
400 /*
401  * Locks:	tty_lock() of old_ptmx_ioctl->pt_tty NOT held for this call.
402  */
403 static int
ptmx_free_ioctl(int minor,int open_flag)404 ptmx_free_ioctl(int minor, int open_flag)
405 {
406 	struct ptmx_ioctl *old_ptmx_ioctl = NULL;
407 
408 	DEVFS_LOCK();
409 
410 	if (minor < 0 || minor >= _state.pis_total) {
411 		DEVFS_UNLOCK();
412 		return -1;
413 	}
414 
415 	_state.pis_ioctl_list[minor]->pt_flags &= ~(open_flag);
416 
417 	/*
418 	 * Was this the last close?  We will recognize it because we only get
419 	 * a notification on the last close of a device, and we will have
420 	 * cleared both the primary and the replica open bits in the flags.
421 	 */
422 	if (!(_state.pis_ioctl_list[minor]->pt_flags & (PF_OPEN_M | PF_OPEN_S))) {
423 		/* Mark as free so it can be reallocated later */
424 		old_ptmx_ioctl = _state.pis_ioctl_list[minor];
425 		_state.pis_ioctl_list[minor] = NULL;
426 		_state.pis_free++;
427 	}
428 	DEVFS_UNLOCK();
429 
430 	/* Free old after dropping lock */
431 	if (old_ptmx_ioctl != NULL) {
432 		/*
433 		 * XXX See <rdar://5348651> and <rdar://4854638>
434 		 *
435 		 * XXX Conditional to be removed when/if tty/pty reference
436 		 * XXX counting and mutex implemented.
437 		 */
438 		if (old_ptmx_ioctl->pt_devhandle != NULL) {
439 			devfs_remove(old_ptmx_ioctl->pt_devhandle);
440 		}
441 		ttyfree(old_ptmx_ioctl->pt_tty);
442 		kfree_type(struct ptmx_ioctl, old_ptmx_ioctl);
443 	}
444 
445 	return 0;     /* Success */
446 }
447 
448 static int
ptmx_get_name(int minor,char * buffer,size_t size)449 ptmx_get_name(int minor, char *buffer, size_t size)
450 {
451 	return snprintf(buffer, size, "/dev/" PTSD_TEMPLATE, minor);
452 }
453 
454 
455 
456 /*
457  * Given the dev entry that's being opened, we clone the device.  This driver
458  * doesn't actually use the dev entry, since we alreaqdy know who we are by
459  * being called from this code.  This routine is a callback registered from
460  * devfs_make_node_clone() in ptmx_init(); it's purpose is to provide a new
461  * minor number, or to return -1, if one can't be provided.
462  *
463  * Parameters:	dev			The device we are cloning from
464  *
465  * Returns:	>= 0			A new minor device number
466  *		-1			Error: ENOMEM ("Can't alloc device")
467  *
468  * NOTE:	Called with DEVFS_LOCK() held
469  */
470 static int
ptmx_clone(__unused dev_t dev,int action)471 ptmx_clone(__unused dev_t dev, int action)
472 {
473 	int i;
474 
475 	if (action == DEVFS_CLONE_ALLOC) {
476 		/* First one */
477 		if (_state.pis_total == 0) {
478 			return 0;
479 		}
480 
481 		/*
482 		 * Note: We can add hinting on free slots, if this linear search
483 		 * ends up being a performance bottleneck...
484 		 */
485 		for (i = 0; i < _state.pis_total; i++) {
486 			if (_state.pis_ioctl_list[i] == NULL) {
487 				break;
488 			}
489 		}
490 
491 		/*
492 		 * XXX We fall off the end here; if we did this twice at the
493 		 * XXX same time, we could return the same minor to two
494 		 * XXX callers; we should probably exand the pointer vector
495 		 * XXX here, but I need more information on the MALLOC/FREE
496 		 * XXX locking to ensure against a deadlock.  Maybe we can
497 		 * XXX just high watermark it at 1/2 of PTMX_GROW_VECTOR?
498 		 * XXX That would require returning &minor as implict return
499 		 * XXX and an error code ("EAGAIN/ERESTART") or 0 as our
500 		 * XXX explicit return.
501 		 */
502 
503 		return i;     /* empty slot or next slot */
504 	}
505 	return -1;
506 }
507 
508 
509 /*
510  * kqueue support.
511  */
512 int ptsd_kqfilter(dev_t dev, struct knote *kn);
513 static void ptsd_kqops_detach(struct knote *);
514 static int ptsd_kqops_event(struct knote *, long);
515 static int ptsd_kqops_touch(struct knote *kn, struct kevent_qos_s *kev);
516 static int ptsd_kqops_process(struct knote *kn, struct kevent_qos_s *kev);
517 
518 SECURITY_READ_ONLY_EARLY(struct filterops) ptsd_kqops = {
519 	.f_isfd = 1,
520 	/* attach is handled by ptsd_kqfilter -- the dev node must be passed in */
521 	.f_detach = ptsd_kqops_detach,
522 	.f_event = ptsd_kqops_event,
523 	.f_touch = ptsd_kqops_touch,
524 	.f_process = ptsd_kqops_process,
525 };
526 
527 /*
528  * In the normal case, by the time the driver_close() routine is called
529  * on the replica, all knotes have been detached.  However in the revoke(2)
530  * case, the driver's close routine is called while there are knotes active
531  * that reference the handlers below.  And we have no obvious means to
532  * reach from the driver out to the kqueue's that reference them to get
533  * them to stop.
534  */
535 
536 static void
ptsd_kqops_detach(struct knote * kn)537 ptsd_kqops_detach(struct knote *kn)
538 {
539 	struct tty *tp = knote_kn_hook_get_raw(kn);
540 	tty_lock(tp);
541 
542 	if (!KNOTE_IS_AUTODETACHED(kn)) {
543 		/*
544 		 * If we got here, it must be due to the fact that we are referencing an open
545 		 * tty - ttyclose always autodetaches knotes under the tty lock and marks
546 		 * the state as closed
547 		 */
548 		assert(tp->t_state & TS_ISOPEN);
549 
550 		switch (kn->kn_filter) {
551 		case EVFILT_READ:
552 			KNOTE_DETACH(&tp->t_rsel.si_note, kn);
553 			break;
554 		case EVFILT_WRITE:
555 			KNOTE_DETACH(&tp->t_wsel.si_note, kn);
556 			break;
557 		default:
558 			panic("invalid knote %p detach, filter: %d", kn, kn->kn_filter);
559 			break;
560 		}
561 	}
562 
563 	knote_kn_hook_set_raw(kn, NULL);
564 
565 	tty_unlock(tp);
566 	ttyfree(tp);
567 }
568 
569 static int
ptsd_kqops_common(struct knote * kn,struct kevent_qos_s * kev,struct tty * tp)570 ptsd_kqops_common(struct knote *kn, struct kevent_qos_s *kev, struct tty *tp)
571 {
572 	int retval = 0;
573 	int64_t data = 0;
574 
575 	TTY_LOCK_OWNED(tp);
576 
577 	switch (kn->kn_filter) {
578 	case EVFILT_READ:
579 		/*
580 		 * ttnread can change the tty state,
581 		 * hence must be done upfront, before any other check.
582 		 */
583 		data = ttnread(tp);
584 		retval = (data > 0);
585 		break;
586 
587 	case EVFILT_WRITE:
588 		if ((tp->t_outq.c_cc <= tp->t_lowat) &&
589 		    (tp->t_state & TS_CONNECTED)) {
590 			data = tp->t_outq.c_cn - tp->t_outq.c_cc;
591 			retval = 1;
592 		}
593 		break;
594 
595 	default:
596 		panic("ptsd kevent: unexpected filter: %d, kn = %p, tty = %p",
597 		    kn->kn_filter, kn, tp);
598 		break;
599 	}
600 
601 	if (tp->t_state & TS_ZOMBIE) {
602 		kn->kn_flags |= EV_EOF;
603 	}
604 	if (kn->kn_flags & EV_EOF) {
605 		retval = 1;
606 	}
607 	if (retval && kev) {
608 		knote_fill_kevent(kn, kev, data);
609 	}
610 	return retval;
611 }
612 
613 static int
ptsd_kqops_event(struct knote * kn,long hint)614 ptsd_kqops_event(struct knote *kn, long hint)
615 {
616 	struct tty *tp = knote_kn_hook_get_raw(kn);
617 	int ret;
618 
619 	TTY_LOCK_OWNED(tp);
620 
621 	if (hint & NOTE_REVOKE) {
622 		kn->kn_flags |= EV_EOF | EV_ONESHOT;
623 		ret = 1;
624 	} else {
625 		ret = ptsd_kqops_common(kn, NULL, tp);
626 	}
627 
628 	return ret;
629 }
630 
631 static int
ptsd_kqops_touch(struct knote * kn,struct kevent_qos_s * kev)632 ptsd_kqops_touch(struct knote *kn, struct kevent_qos_s *kev)
633 {
634 	struct tty *tp = knote_kn_hook_get_raw(kn);
635 	int ret;
636 
637 	tty_lock(tp);
638 
639 	/* accept new kevent state */
640 	kn->kn_sfflags = kev->fflags;
641 	kn->kn_sdata = kev->data;
642 
643 	/* recapture fired state of knote */
644 	ret = ptsd_kqops_common(kn, NULL, tp);
645 
646 	tty_unlock(tp);
647 
648 	return ret;
649 }
650 
651 static int
ptsd_kqops_process(struct knote * kn,struct kevent_qos_s * kev)652 ptsd_kqops_process(struct knote *kn, struct kevent_qos_s *kev)
653 {
654 	struct tty *tp = knote_kn_hook_get_raw(kn);
655 	int ret;
656 
657 	tty_lock(tp);
658 	ret = ptsd_kqops_common(kn, kev, tp);
659 	tty_unlock(tp);
660 
661 	return ret;
662 }
663 
664 int
ptsd_kqfilter(dev_t dev,struct knote * kn)665 ptsd_kqfilter(dev_t dev, struct knote *kn)
666 {
667 	struct tty *tp = NULL;
668 	struct ptmx_ioctl *pti = NULL;
669 	int ret;
670 
671 	/* make sure we're talking about the right device type */
672 	if (cdevsw[major(dev)].d_open != ptsopen) {
673 		knote_set_error(kn, ENODEV);
674 		return 0;
675 	}
676 
677 	if ((pti = ptmx_get_ioctl(minor(dev), 0)) == NULL) {
678 		knote_set_error(kn, ENXIO);
679 		return 0;
680 	}
681 
682 	tp = pti->pt_tty;
683 	tty_lock(tp);
684 
685 	assert(tp->t_state & TS_ISOPEN);
686 
687 	kn->kn_filtid = EVFILTID_PTSD;
688 	/* the tty will be freed when detaching the knote */
689 	ttyhold(tp);
690 	knote_kn_hook_set_raw(kn, tp);
691 
692 	switch (kn->kn_filter) {
693 	case EVFILT_READ:
694 		KNOTE_ATTACH(&tp->t_rsel.si_note, kn);
695 		break;
696 	case EVFILT_WRITE:
697 		KNOTE_ATTACH(&tp->t_wsel.si_note, kn);
698 		break;
699 	default:
700 		panic("ptsd kevent: unexpected filter: %d, kn = %p, tty = %p",
701 		    kn->kn_filter, kn, tp);
702 		break;
703 	}
704 
705 	/* capture current event state */
706 	ret = ptsd_kqops_common(kn, NULL, tp);
707 
708 	tty_unlock(tp);
709 
710 	return ret;
711 }
712 
713 /*
714  * Support for revoke(2).
715  */
716 static void
ptsd_revoke_knotes(__unused int minor,struct tty * tp)717 ptsd_revoke_knotes(__unused int minor, struct tty *tp)
718 {
719 	tty_lock(tp);
720 
721 	ttwakeup(tp);
722 	assert((tp->t_rsel.si_flags & SI_KNPOSTING) == 0);
723 	knote(&tp->t_rsel.si_note, NOTE_REVOKE, true);
724 
725 	ttwwakeup(tp);
726 	assert((tp->t_wsel.si_flags & SI_KNPOSTING) == 0);
727 	knote(&tp->t_wsel.si_note, NOTE_REVOKE, true);
728 
729 	tty_unlock(tp);
730 }
731 
732 /*
733  * kevent filter routines for the master side of a pty, a ptmx.
734  *
735  * Stuff the ptmx_ioctl structure into the hook for ptmx knotes.  Use the
736  * embedded tty's lock for synchronization.
737  */
738 
739 int ptmx_kqfilter(dev_t dev, struct knote *kn);
740 static void ptmx_kqops_detach(struct knote *);
741 static int ptmx_kqops_event(struct knote *, long);
742 static int ptmx_kqops_touch(struct knote *kn, struct kevent_qos_s *kev);
743 static int ptmx_kqops_process(struct knote *kn, struct kevent_qos_s *kev);
744 static int ptmx_kqops_common(struct knote *kn, struct kevent_qos_s *kev,
745     struct ptmx_ioctl *pti, struct tty *tp);
746 
747 SECURITY_READ_ONLY_EARLY(struct filterops) ptmx_kqops = {
748 	.f_isfd = 1,
749 	/* attach is handled by ptmx_kqfilter -- the dev node must be passed in */
750 	.f_detach = ptmx_kqops_detach,
751 	.f_event = ptmx_kqops_event,
752 	.f_touch = ptmx_kqops_touch,
753 	.f_process = ptmx_kqops_process,
754 };
755 
756 static struct ptmx_ioctl *
ptmx_knote_ioctl(struct knote * kn)757 ptmx_knote_ioctl(struct knote *kn)
758 {
759 	return (struct ptmx_ioctl *)knote_kn_hook_get_raw(kn);
760 }
761 
762 static struct tty *
ptmx_knote_tty(struct knote * kn)763 ptmx_knote_tty(struct knote *kn)
764 {
765 	return ptmx_knote_ioctl(kn)->pt_tty;
766 }
767 
768 int
ptmx_kqfilter(dev_t dev,struct knote * kn)769 ptmx_kqfilter(dev_t dev, struct knote *kn)
770 {
771 	struct tty *tp = NULL;
772 	struct ptmx_ioctl *pti = NULL;
773 	int ret;
774 
775 	/* make sure we're talking about the right device type */
776 	if (cdevsw[major(dev)].d_open != ptcopen) {
777 		knote_set_error(kn, ENODEV);
778 		return 0;
779 	}
780 
781 	if ((pti = ptmx_get_ioctl(minor(dev), 0)) == NULL) {
782 		knote_set_error(kn, ENXIO);
783 		return 0;
784 	}
785 
786 	tp = pti->pt_tty;
787 	tty_lock(tp);
788 
789 	kn->kn_filtid = EVFILTID_PTMX;
790 	/* the tty will be freed when detaching the knote */
791 	ttyhold(tp);
792 	knote_kn_hook_set_raw(kn, pti);
793 
794 	/*
795 	 * Attach to the ptmx's selinfo structures.  This is the major difference
796 	 * to the ptsd filtops, which use the selinfo structures in the tty
797 	 * structure.
798 	 */
799 	switch (kn->kn_filter) {
800 	case EVFILT_READ:
801 		KNOTE_ATTACH(&pti->pt_selr.si_note, kn);
802 		break;
803 	case EVFILT_WRITE:
804 		KNOTE_ATTACH(&pti->pt_selw.si_note, kn);
805 		break;
806 	default:
807 		panic("ptmx kevent: unexpected filter: %d, kn = %p, tty = %p",
808 		    kn->kn_filter, kn, tp);
809 		break;
810 	}
811 
812 	/* capture current event state */
813 	ret = ptmx_kqops_common(kn, NULL, pti, tp);
814 
815 	tty_unlock(tp);
816 
817 	return ret;
818 }
819 
820 static void
ptmx_kqops_detach(struct knote * kn)821 ptmx_kqops_detach(struct knote *kn)
822 {
823 	struct ptmx_ioctl *pti = knote_kn_hook_get_raw(kn);
824 	struct tty *tp = pti->pt_tty;
825 
826 	tty_lock(tp);
827 
828 	if (!KNOTE_IS_AUTODETACHED(kn)) {
829 		switch (kn->kn_filter) {
830 		case EVFILT_READ:
831 			KNOTE_DETACH(&pti->pt_selr.si_note, kn);
832 			break;
833 		case EVFILT_WRITE:
834 			KNOTE_DETACH(&pti->pt_selw.si_note, kn);
835 			break;
836 		default:
837 			panic("invalid knote %p detach, filter: %d", kn, kn->kn_filter);
838 			break;
839 		}
840 	}
841 
842 	knote_kn_hook_set_raw(kn, NULL);
843 
844 	tty_unlock(tp);
845 	ttyfree(tp);
846 }
847 
848 static int
ptmx_kqops_common(struct knote * kn,struct kevent_qos_s * kev,struct ptmx_ioctl * pti,struct tty * tp)849 ptmx_kqops_common(struct knote *kn, struct kevent_qos_s *kev,
850     struct ptmx_ioctl *pti, struct tty *tp)
851 {
852 	int retval = 0;
853 	int64_t data = 0;
854 
855 	TTY_LOCK_OWNED(tp);
856 
857 	switch (kn->kn_filter) {
858 	case EVFILT_READ:
859 		/* there's data on the TTY and it's not stopped */
860 		if (tp->t_outq.c_cc && !(tp->t_state & TS_TTSTOP)) {
861 			data = tp->t_outq.c_cc;
862 			retval = data > 0;
863 		} else if (((pti->pt_flags & PF_PKT) && pti->pt_send) ||
864 		    ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl)) {
865 			retval = 1;
866 		}
867 		break;
868 
869 	case EVFILT_WRITE:
870 		retval = (TTYHOG - 2) - (tp->t_rawq.c_cc + tp->t_canq.c_cc);
871 		if (tp->t_canq.c_cc == 0 && (tp->t_lflag & ICANON)) {
872 			retval = 1;
873 		}
874 		if (retval < 0) {
875 			retval = 0;
876 		}
877 		break;
878 
879 	default:
880 		panic("ptmx kevent: unexpected filter: %d, kn = %p, tty = %p",
881 		    kn->kn_filter, kn, tp);
882 		break;
883 	}
884 
885 	/* disconnects should force a wakeup (EOF) */
886 	if (!(tp->t_state & TS_CONNECTED) || (tp->t_state & TS_ZOMBIE)) {
887 		kn->kn_flags |= EV_EOF;
888 	}
889 	if (kn->kn_flags & EV_EOF) {
890 		retval = 1;
891 	}
892 	if (retval && kev) {
893 		knote_fill_kevent(kn, kev, data);
894 	}
895 	return retval;
896 }
897 
898 static int
ptmx_kqops_event(struct knote * kn,long hint)899 ptmx_kqops_event(struct knote *kn, long hint)
900 {
901 	struct ptmx_ioctl *pti = ptmx_knote_ioctl(kn);
902 	struct tty *tp = ptmx_knote_tty(kn);
903 	int ret;
904 
905 	TTY_LOCK_OWNED(tp);
906 
907 	if (hint & NOTE_REVOKE) {
908 		kn->kn_flags |= EV_EOF | EV_ONESHOT;
909 		ret = 1;
910 	} else {
911 		ret = ptmx_kqops_common(kn, NULL, pti, tp);
912 	}
913 
914 	return ret;
915 }
916 
917 static int
ptmx_kqops_touch(struct knote * kn,struct kevent_qos_s * kev)918 ptmx_kqops_touch(struct knote *kn, struct kevent_qos_s *kev)
919 {
920 	struct ptmx_ioctl *pti = ptmx_knote_ioctl(kn);
921 	struct tty *tp = ptmx_knote_tty(kn);
922 	int ret;
923 
924 	tty_lock(tp);
925 
926 	/* accept new kevent state */
927 	kn->kn_sfflags = kev->fflags;
928 	kn->kn_sdata = kev->data;
929 
930 	/* recapture fired state of knote */
931 	ret = ptmx_kqops_common(kn, NULL, pti, tp);
932 
933 	tty_unlock(tp);
934 
935 	return ret;
936 }
937 
938 static int
ptmx_kqops_process(struct knote * kn,struct kevent_qos_s * kev)939 ptmx_kqops_process(struct knote *kn, struct kevent_qos_s *kev)
940 {
941 	struct ptmx_ioctl *pti = ptmx_knote_ioctl(kn);
942 	struct tty *tp = ptmx_knote_tty(kn);
943 	int ret;
944 
945 	tty_lock(tp);
946 	ret = ptmx_kqops_common(kn, kev, pti, tp);
947 	tty_unlock(tp);
948 
949 	return ret;
950 }
951