Date: Fri, 24 Oct 1997 13:08:26 -0400 (EDT) From: spork <spork@super-g.com> To: tqbf@enteract.com Cc: freebsd-security@FreeBSD.ORG Subject: Re: BoS: Possible SERIOUS bug in open()? (fwd) Message-ID: <Pine.BSF.3.96.971024125748.21468B-100000@super-g.inch.com> In-Reply-To: <19971023063636.19963.qmail@joshua.enteract.com>
next in thread | previous in thread | raw e-mail | index | archive | help
I see a fix for RELENG_2_2 at: http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/kern/vfs_syscalls.c but has anyone by chance back-ported this to 2.1.x? Thanks, Charles On 23 Oct 1997 tqbf@joshua.enteract.com wrote: > In muc.lists.freebsd.security, you wrote: > > fd = open("/dev/rsd0a", -1, 0); > > Yep. This definitely works on {Free,Net,Open}BSD. > > This is a variant of a bug Theo de Raadt found in SunOS back in the 1980s. > The basic issue is that the code that guards access to the device-specific > open() routine checks explicitly for FREAD, FWRITE, and O_TRUNC, and > passes the call through if none of these are set. Theo's bug involved > using "3" for the open() flag. > > The problem here is that before calls to open() are even passed to the > vnode open() routine (after the vnode is looked up by the generic > vfs_syscalls open() syscall handler), the flags field is incremented by > one: > > vfs_syscalls.c:open() > > ... > > flags = FFLAGS(uap->flags); > > ... > > where FFLAGS() is: > > ./sys/fcntl.h:#define FFLAGS(oflags) ((oflags) + 1) > > As you can see, passing a "-1" to open() will result in "flags" becoming > "0" - open() ordinarily never passes "0" to the vnode code, since "0" > becomes "1" after being converted to fflags format. > > A fun game you can play with practically no programming ability is to > exploit the fact that some devices will initialize themselves immediately > upon being opened - particularly amusing is the SCSI tape driver, > sys/scsi/st.c, which will rewind itself when opened. Simply run the > previously posted example code on /dev/rst0 and destroy tonight's backup. > > If you want to hack this fixed in FreeBSD, you can apply the enclosed diff > to your kernel; this is a total hack, and someone else will provide a > "correct" fix soon enough. > > Incidentally, this is yet another piece of evidence supporting the > presence of another systemic secure-coding problem - sanity checking > integer arguments and guarding against overflow. This is far from the only > place that I've seen problems with unexpected interactions owing to > surprise negative arguments. Anyone want to take a guess as to what > strncpy() does when it gets a negative "count" argument? Think that can't > happen? Think pointer arithmetic. > > -- > ----------------------------------------------------------------------------- > Thomas H. Ptacek Secure Networks, Inc. > ----------------------------------------------------------------------------- > "mmm... sacrilicious..." > > --- vfs_syscalls.c-orig Thu Oct 23 01:21:58 1997 > +++ vfs_syscalls.c Thu Oct 23 01:21:19 1997 > @@ -690,6 +690,9 @@ > return (error); > fp = nfp; > flags = FFLAGS(uap->flags); > + if(!flags) > + flags++; > + > cmode = ((uap->mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; > NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p); > p->p_dupfd = -indx - 1; /* XXX check for fdopen */ >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.96.971024125748.21468B-100000>