Xref: utzoo comp.unix.wizards:25396 alt.security:2437 Path: utzoo!utgpu!cs.utexas.edu!usc!zaphod.mps.ohio-state.edu!mips!pacbell.com!ucsd!sdcc6!sdcc10!muller From: muller@sdcc10.ucsd.edu (Keith Muller) Newsgroups: comp.unix.wizards,alt.security Subject: Re: BSD tty security, part 3: How to Fix It Message-ID: <19002@sdcc6.ucsd.edu> Date: 4 May 91 22:46:15 GMT References: <18924@sdcc6.ucsd.edu> <15369:May219:46:0491@kramden.acf.nyu.edu> <1237:May321:05:0191@kramden.acf.nyu.edu> Sender: news@sdcc6.ucsd.edu Followup-To: comp.unix.wizards,alt.security Lines: 167 In article <1237:May321:05:0191@kramden.acf.nyu.edu>, brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: > > (It will work for hardwired ttys if you make the outlined changes to > getty's initialization routine. But without a secure break key [as you > can implement with my suggestion #24], hardwired ttys are completely > insecure anyway.) Why should hardwire ttys be insecure? Login session terminal termination occurs when either the login shell exits or dcd drops (assuming -nohang is set). Preventing login just because a background job is referencing a tty is not acceptable. If I read #24 correctly you want to force ttys through ptys? (connecting the master side with a pipe through the hardwire port). So ptys are the only thing used for login sessions.... Sure is a lot of overhead (in and out of user mode multiple times to move data). > And once you have included special treatment of that flag in every > single tty operation. This is a lot of kernel work. Why do you refuse to > write out these changes at a sufficiently low level of detail that > people can implement them? If it's so few lines of code, why don't you > write out the code? I am not trying to promote a fix, but promote a discussion on how to address tty semantics . The only reason I even answer your postings is to point out that other METHODS exsist. The code to check access is simple and the majority of the tests are already is in the kernel. I am looking at the code (4.3 reno) right now. On entry point in the kernel for read() for example we see: if (((unsigned)uap->fdes) >= NOFILE || (fp = u.u_ofile[uap->fdes]) == NULL || (fp->f_flag & FREAD) == 0) return (EBADF); Now tell me the open file table access rights for the read isn't being done here.... Traversing the open file table on device deallocation is not a lot of code. Vhangup() (aka forceclose()) does it already (from 4.3 tahoe): forceclose(dev) dev_t dev; { register struct file *fp; register struct inode *ip; for (fp = file; fp < fileNFILE; fp++) { if (fp->f_count == 0) continue; if (fp->f_type != DTYPE_INODE) continue; ip = (struct inode *)fp->f_data; if (ip == 0) continue; if ((ip->i_mode & IFMT) != IFCHR) continue; if (ip->i_rdev != dev) continue; fp->f_flag &= ~(FREAD|FWRITE); } } So even by revoking access the way vhangup does (by removind read/write access and not using an additional flag) the code is small. Deallocation of ttys is not a very highly called occurance to consider the above loop "intensive". (it is certainly a lot less load than what I think you want to do to the data flow on herdware ttys). Actually in both this and your method the case where multiple (v)(i)nodes reference the same device probably should be addressed (even if it is a questionable thing to do).. > ttyd is standard BSD, and is on the vast majority of BSD-derived > systems. ttyvp only appears on Suns, very recent (i.e. non-production) > BSD releases, and possibly some obscure or extremely recently released > systems that I'm not familiar with. Looking at the source for 4.3 tahoe there is no p_ttyd or u_ttyd. All tty references use the open file table. Access removed there terminates access to the tty. If f_flag permissions (or a revoked flag if you want to do it that way) (or even more strongly if f_data does not reference the active inode in the kernel), that fd cannot do i/o. In the 4.3 reno you get from CSRG, ttyvp does exsist (see kern/tty_tty.c). > I repeat my claim: your changes don't close the holes on anything but > Suns and very recent BSD releases (such as Reno). In fact, unless you > know you've changed every single tty operation to check that flag and > behave properly, including when coming out of sleep, your changes are > insecure even on those systems. There about 17 places where you sleep on read/write and ioctl for tty ops. All in tty.c and tty_pty.c (all have similar code fragments, many of which relate to hanging background operations). In most places the sleep is followed by a goto to the top (entry point) of the routine. At the top is one place the check could be done. For example the sleep() fragment in ttread() (from 4.3 tahoe) looks like: if (tp == u.u_ttyp && u.u_procp->p_pgrp != tp->t_pgrp) { if ((u.u_procp->p_sigignore & sigmask(SIGTTIN)) || (u.u_procp->p_sigmask & sigmask(SIGTTIN)) || u.u_procp->p_flag&SVFORK) return (EIO); gsignal(u.u_procp->p_pgrp, SIGTTIN); sleep((caddr_t)&lbolt, TTIPRI); goto loop; } Now loop is at the top of the routine. Adding the following line (assuming you pass the tty struct to the routines) does the check for read for example. (the if statement after the loop: is what is added).This uses a access restriction scheme like vhangup (not an added flag but removing the read/write flags as demonstrated in forceclose() above. loop: if ((fp->f_flag & FREAD) == 0) return(EBADF); > > But you want people to add an extra check, plus have it handled for > blocking processes. I repeat my claim. This is the only check added. Not a significant consumption of time. (You could just make it a macro and put it after each sleep if you want to trade space for time). >> On 4.3 RENO and earlier there is only u_ttyvp, so that replacement >> is not needed. > This statement is simply incorrect. On BSD 4.3 Reno and LATER there is > u_ttyvp. I believe that they took the name and idea from SunOS, though > I'll have to check this with Marc Teitelbaum. Yes a typo on my part. (The earlier should be later, the surrounding paragraphs did support the corrected statement). > > Damn it, I can't stay polite about this. You obviously aren't familiar > with a wide range of machines---your statements about u_ttyvp prove > that. Your fixes do not work on most machines, but you say they do > because you don't know what you're doing. This is exactly the kind of > sheer idiocy that has let to the current situation: nobody fixes the > .... Excuse me but I am only illustrating a different technique does exsist and never stated I was providing a fix to all variants of UNIX.. I simply used BSD as a counter example in my posting as an alternate to what you start out saying when you descibe your fixes: >Here's one way to fix the BSD 4.[234] tty system, i.e., to provide some And thats what I desribed, a technique for the BSD 4.[234] tty system. If some vendor adds a tty device or tty access method in THEIR operating system that does not use the open file table like 4.[234] does then they should rethink the reasons why it was done. (maybe throwing out the open file table is a reasonable thing and should be done, but that is not what this discussion is about). Unless you are looking at a different BSD kernel source than I, your statements about tty i/o access in BSD (tahoe or reno) is in error. Please look at the actual kernel code before "shooting from the hip". Keith Muller University of California