Date: 23 Oct 1997 06:36:36 -0000 From: tqbf@joshua.enteract.com To: dima@best.net, freebsd-security@freebsd.org Subject: Re: BoS: Possible SERIOUS bug in open()? (fwd) Message-ID: <19971023063636.19963.qmail@joshua.enteract.com> In-Reply-To: <199710230500.WAA11569@burka.rdy.com>
next in thread | previous in thread | raw e-mail | index | archive | help
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?19971023063636.19963.qmail>