From owner-freebsd-security Fri Oct 24 10:10:57 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id KAA04461 for security-outgoing; Fri, 24 Oct 1997 10:10:57 -0700 (PDT) (envelope-from owner-freebsd-security) Received: from super-g.inch.com (super-g.com [207.240.140.161]) by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id KAA04453 for ; Fri, 24 Oct 1997 10:10:54 -0700 (PDT) (envelope-from spork@super-g.com) Received: from localhost (spork@localhost) by super-g.inch.com (8.8.7/8.8.5) with SMTP id NAA22575; Fri, 24 Oct 1997 13:08:26 -0400 (EDT) Date: Fri, 24 Oct 1997 13:08:26 -0400 (EDT) From: spork X-Sender: spork@super-g.inch.com To: tqbf@enteract.com cc: freebsd-security@FreeBSD.ORG Subject: Re: BoS: Possible SERIOUS bug in open()? (fwd) In-Reply-To: <19971023063636.19963.qmail@joshua.enteract.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-security@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk 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 */ >