1 /* $OpenBSD: tty_tty.c,v 1.31 2022/07/02 08:50:42 visa Exp $ */ 2 /* $NetBSD: tty_tty.c,v 1.13 1996/03/30 22:24:46 christos Exp $ */ 3 4 /*- 5 * Copyright (c) 1982, 1986, 1991, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * @(#)tty_tty.c 8.2 (Berkeley) 9/23/93 33 */ 34 35 /* 36 * Indirect driver for controlling tty. 37 */ 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/ioctl.h> 41 #include <sys/proc.h> 42 #include <sys/tty.h> 43 #include <sys/vnode.h> 44 #include <sys/lock.h> 45 #include <sys/fcntl.h> 46 47 48 #define cttyvp(p) \ 49 ((p)->p_p->ps_flags & PS_CONTROLT ? \ 50 (p)->p_p->ps_session->s_ttyvp : NULL) 51 52 int 53 cttyopen(dev_t dev, int flag, int mode, struct proc *p) 54 { 55 struct vnode *ttyvp = cttyvp(p); 56 int error; 57 58 if (ttyvp == NULL) 59 return (ENXIO); 60 vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY); 61 error = VOP_OPEN(ttyvp, flag, NOCRED, p); 62 VOP_UNLOCK(ttyvp); 63 return (error); 64 } 65 66 int 67 cttyread(dev_t dev, struct uio *uio, int flag) 68 { 69 struct vnode *ttyvp = cttyvp(uio->uio_procp); 70 int error; 71 72 if (ttyvp == NULL) 73 return (EIO); 74 vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY); 75 error = VOP_READ(ttyvp, uio, flag, NOCRED); 76 VOP_UNLOCK(ttyvp); 77 return (error); 78 } 79 80 int 81 cttywrite(dev_t dev, struct uio *uio, int flag) 82 { 83 struct vnode *ttyvp = cttyvp(uio->uio_procp); 84 int error; 85 86 if (ttyvp == NULL) 87 return (EIO); 88 vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY); 89 error = VOP_WRITE(ttyvp, uio, flag, NOCRED); 90 VOP_UNLOCK(ttyvp); 91 return (error); 92 } 93 94 int 95 cttyioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) 96 { 97 struct vnode *ttyvp = cttyvp(p); 98 struct session *sess; 99 int error, secs; 100 101 if (ttyvp == NULL) 102 return (EIO); 103 if (cmd == TIOCSCTTY) /* XXX */ 104 return (EINVAL); 105 if (cmd == TIOCNOTTY) { 106 if (!SESS_LEADER(p->p_p)) { 107 atomic_clearbits_int(&p->p_p->ps_flags, PS_CONTROLT); 108 return (0); 109 } else 110 return (EINVAL); 111 } 112 switch (cmd) { 113 case TIOCSETVERAUTH: 114 if ((error = suser(p))) 115 return error; 116 secs = *(int *)addr; 117 if (secs < 1 || secs > 3600) 118 return EINVAL; 119 sess = p->p_p->ps_pgrp->pg_session; 120 sess->s_verauthuid = p->p_ucred->cr_ruid; 121 sess->s_verauthppid = p->p_p->ps_pptr->ps_pid; 122 timeout_add_sec(&sess->s_verauthto, secs); 123 return 0; 124 case TIOCCLRVERAUTH: 125 sess = p->p_p->ps_pgrp->pg_session; 126 timeout_del(&sess->s_verauthto); 127 zapverauth(sess); 128 return 0; 129 case TIOCCHKVERAUTH: 130 /* 131 * It's not clear when or what these checks are for. 132 * How can we reach this code with a different ruid? 133 * The ppid check is also more porous than desired. 134 * Nevertheless, the checks reflect the original intention; 135 * namely, that it be the same user using the same shell. 136 */ 137 sess = p->p_p->ps_pgrp->pg_session; 138 if (sess->s_verauthuid == p->p_ucred->cr_ruid && 139 sess->s_verauthppid == p->p_p->ps_pptr->ps_pid) 140 return 0; 141 return EPERM; 142 } 143 return (VOP_IOCTL(ttyvp, cmd, addr, flag, NOCRED, p)); 144 } 145 146 int 147 cttykqfilter(dev_t dev, struct knote *kn) 148 { 149 struct vnode *ttyvp = cttyvp(curproc); 150 151 if (ttyvp == NULL) { 152 if (kn->kn_flags & (__EV_POLL | __EV_SELECT)) 153 return (seltrue_kqfilter(dev, kn)); 154 return (ENXIO); 155 } 156 return (VOP_KQFILTER(ttyvp, FREAD|FWRITE, kn)); 157 } 158