1 1.41 ad /* $NetBSD: tty_tty.c,v 1.41 2020/05/23 23:42:43 ad Exp $ */ 2 1.10 cgd 3 1.1 cgd /*- 4 1.15 fvdl * Copyright (c) 1982, 1986, 1991, 1993, 1995 5 1.9 cgd * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * Redistribution and use in source and binary forms, with or without 8 1.1 cgd * modification, are permitted provided that the following conditions 9 1.1 cgd * are met: 10 1.1 cgd * 1. Redistributions of source code must retain the above copyright 11 1.1 cgd * notice, this list of conditions and the following disclaimer. 12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 cgd * notice, this list of conditions and the following disclaimer in the 14 1.1 cgd * documentation and/or other materials provided with the distribution. 15 1.22 agc * 3. Neither the name of the University nor the names of its contributors 16 1.1 cgd * may be used to endorse or promote products derived from this software 17 1.1 cgd * without specific prior written permission. 18 1.1 cgd * 19 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 cgd * SUCH DAMAGE. 30 1.1 cgd * 31 1.10 cgd * @(#)tty_tty.c 8.2 (Berkeley) 9/23/93 32 1.1 cgd */ 33 1.1 cgd 34 1.1 cgd /* 35 1.1 cgd * Indirect driver for controlling tty. 36 1.1 cgd */ 37 1.17 lukem 38 1.17 lukem #include <sys/cdefs.h> 39 1.41 ad __KERNEL_RCSID(0, "$NetBSD: tty_tty.c,v 1.41 2020/05/23 23:42:43 ad Exp $"); 40 1.17 lukem 41 1.7 mycroft #include <sys/param.h> 42 1.7 mycroft #include <sys/systm.h> 43 1.7 mycroft #include <sys/ioctl.h> 44 1.9 cgd #include <sys/proc.h> 45 1.7 mycroft #include <sys/tty.h> 46 1.7 mycroft #include <sys/vnode.h> 47 1.7 mycroft #include <sys/file.h> 48 1.13 christos #include <sys/conf.h> 49 1.28 elad #include <sys/kauth.h> 50 1.1 cgd 51 1.32 ad /* XXXSMP */ 52 1.32 ad #define cttyvp(p) ((p)->p_lflag & PL_CONTROLT ? (p)->p_session->s_ttyvp : NULL) 53 1.18 gehenna 54 1.1 cgd /*ARGSUSED*/ 55 1.25 thorpej static int 56 1.31 yamt cttyopen(dev_t dev, int flag, int mode, struct lwp *l) 57 1.1 cgd { 58 1.26 christos struct vnode *ttyvp = cttyvp(l->l_proc); 59 1.1 cgd int error; 60 1.1 cgd 61 1.1 cgd if (ttyvp == NULL) 62 1.1 cgd return (ENXIO); 63 1.15 fvdl vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY); 64 1.9 cgd #ifdef PARANOID 65 1.9 cgd /* 66 1.9 cgd * Since group is tty and mode is 620 on most terminal lines 67 1.9 cgd * and since sessions protect terminals from processes outside 68 1.9 cgd * your session, this check is probably no longer necessary. 69 1.24 perry * Since it inhibits setuid root programs that later switch 70 1.9 cgd * to another user from accessing /dev/tty, we have decided 71 1.9 cgd * to delete this test. (mckusick 5/93) 72 1.9 cgd */ 73 1.1 cgd error = VOP_ACCESS(ttyvp, 74 1.29 ad (flag&FREAD ? VREAD : 0) | (flag&FWRITE ? VWRITE : 0), l->l_cred, l); 75 1.1 cgd if (!error) 76 1.9 cgd #endif /* PARANOID */ 77 1.36 pooka error = VOP_OPEN(ttyvp, flag, NOCRED); 78 1.38 hannken VOP_UNLOCK(ttyvp); 79 1.1 cgd return (error); 80 1.1 cgd } 81 1.1 cgd 82 1.1 cgd /*ARGSUSED*/ 83 1.25 thorpej static int 84 1.31 yamt cttyread(dev_t dev, struct uio *uio, int flag) 85 1.1 cgd { 86 1.27 yamt struct vnode *ttyvp = cttyvp(curproc); 87 1.1 cgd int error; 88 1.1 cgd 89 1.1 cgd if (ttyvp == NULL) 90 1.1 cgd return (EIO); 91 1.15 fvdl vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY); 92 1.1 cgd error = VOP_READ(ttyvp, uio, flag, NOCRED); 93 1.38 hannken VOP_UNLOCK(ttyvp); 94 1.1 cgd return (error); 95 1.1 cgd } 96 1.1 cgd 97 1.1 cgd /*ARGSUSED*/ 98 1.25 thorpej static int 99 1.31 yamt cttywrite(dev_t dev, struct uio *uio, int flag) 100 1.1 cgd { 101 1.27 yamt struct vnode *ttyvp = cttyvp(curproc); 102 1.1 cgd int error; 103 1.1 cgd 104 1.1 cgd if (ttyvp == NULL) 105 1.1 cgd return (EIO); 106 1.15 fvdl vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY); 107 1.1 cgd error = VOP_WRITE(ttyvp, uio, flag, NOCRED); 108 1.38 hannken VOP_UNLOCK(ttyvp); 109 1.1 cgd return (error); 110 1.1 cgd } 111 1.1 cgd 112 1.1 cgd /*ARGSUSED*/ 113 1.25 thorpej static int 114 1.33 christos cttyioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) 115 1.20 darrenr { 116 1.26 christos struct vnode *ttyvp = cttyvp(l->l_proc); 117 1.32 ad int rv; 118 1.1 cgd 119 1.1 cgd if (ttyvp == NULL) 120 1.1 cgd return (EIO); 121 1.9 cgd if (cmd == TIOCSCTTY) /* XXX */ 122 1.6 deraadt return (EINVAL); 123 1.1 cgd if (cmd == TIOCNOTTY) { 124 1.41 ad mutex_enter(&proc_lock); 125 1.26 christos if (!SESS_LEADER(l->l_proc)) { 126 1.32 ad l->l_proc->p_lflag &= ~PL_CONTROLT; 127 1.32 ad rv = 0; 128 1.1 cgd } else 129 1.32 ad rv = EINVAL; 130 1.41 ad mutex_exit(&proc_lock); 131 1.32 ad return (rv); 132 1.1 cgd } 133 1.36 pooka return (VOP_IOCTL(ttyvp, cmd, addr, flag, NOCRED)); 134 1.1 cgd } 135 1.1 cgd 136 1.1 cgd /*ARGSUSED*/ 137 1.25 thorpej static int 138 1.26 christos cttypoll(dev_t dev, int events, struct lwp *l) 139 1.20 darrenr { 140 1.26 christos struct vnode *ttyvp = cttyvp(l->l_proc); 141 1.1 cgd 142 1.1 cgd if (ttyvp == NULL) 143 1.26 christos return (seltrue(dev, events, l)); 144 1.36 pooka return (VOP_POLL(ttyvp, events)); 145 1.19 jdolecek } 146 1.19 jdolecek 147 1.25 thorpej static int 148 1.31 yamt cttykqfilter(dev_t dev, struct knote *kn) 149 1.19 jdolecek { 150 1.19 jdolecek /* This is called from filt_fileattach() by the attaching process. */ 151 1.19 jdolecek struct proc *p = curproc; 152 1.19 jdolecek struct vnode *ttyvp = cttyvp(p); 153 1.19 jdolecek 154 1.19 jdolecek if (ttyvp == NULL) 155 1.19 jdolecek return (1); 156 1.19 jdolecek return (VOP_KQFILTER(ttyvp, kn)); 157 1.1 cgd } 158 1.25 thorpej 159 1.25 thorpej const struct cdevsw ctty_cdevsw = { 160 1.39 dholland .d_open = cttyopen, 161 1.39 dholland .d_close = nullclose, 162 1.39 dholland .d_read = cttyread, 163 1.39 dholland .d_write = cttywrite, 164 1.39 dholland .d_ioctl = cttyioctl, 165 1.39 dholland .d_stop = nullstop, 166 1.39 dholland .d_tty = notty, 167 1.39 dholland .d_poll = cttypoll, 168 1.39 dholland .d_mmap = nommap, 169 1.39 dholland .d_kqfilter = cttykqfilter, 170 1.40 dholland .d_discard = nodiscard, 171 1.39 dholland .d_flag = D_TTY 172 1.25 thorpej }; 173