Date: Tue, 24 Jul 2001 00:36:54 -0500 From: Alfred Perlstein <bright@sneakerz.org> To: Kris Kennaway <kris@obsecurity.org> Cc: fs@FreeBSD.org, tanimura@freebsd.org Subject: Re: [viro@math.psu.edu: Locally exploitable races in OpenBSD VFS] Message-ID: <20010724003654.B68587@sneakerz.org> In-Reply-To: <20010723202526.B96630@xor.obsecurity.org>; from kris@obsecurity.org on Mon, Jul 23, 2001 at 08:25:27PM -0700 References: <20010723202526.B96630@xor.obsecurity.org>
next in thread | previous in thread | raw e-mail | index | archive | help
* Kris Kennaway <kris@obsecurity.org> [010723 22:25] wrote: > Has anyone looked at whether these apply to us? It's possible, Tanimura and I are working on a patchset dealing with shared filedescriptors and SMP, we'll let keep you updated. > > Kris > > ----- Forwarded message from Alexander Viro <viro@math.psu.edu> ----- > > Delivered-To: kkenn@localhost.obsecurity.org > Date: Sat, 02 Jun 2001 19:00:08 -0400 (EDT) > From: Alexander Viro <viro@math.psu.edu> > Subject: Locally exploitable races in OpenBSD VFS > To: BUGTRAQ@securityfocus.com > Precedence: bulk > Delivered-to: kris@freebsd.org > Delivered-to: mailing list bugtraq@securityfocus.com > Delivered-to: moderator for bugtraq@securityfocus.com > Mailing-List: contact bugtraq-help@securityfocus.com; run by ezmlm > List-Id: <bugtraq.list-id.securityfocus.com> > List-Post: <mailto:bugtraq@securityfocus.com> > List-Help: <mailto:bugtraq-help@securityfocus.com> > List-Unsubscribe: <mailto:bugtraq-unsubscribe@securityfocus.com> > List-Subscribe: <mailto:bugtraq-subscribe@securityfocus.com> > X-Authentication-warning: weyl.math.psu.edu: viro owned process doing -bs > > [my apologies if it ends up submitted twice] > Let's start with the trivial: good old aliasing bugs. > > Example 1: > dup2() vs. close(). Relevant file: kern/kern_descrip.c > > sys_dup2(p, v, retval) > struct proc *p; > void *v; > register_t *retval; > { > [snip] > if ((u_int)old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL || > (u_int)new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur || > (u_int)new >= maxfiles) > return (EBADF); > OK, we've checked (among other things) that old is indeed opened. > [snip] > if (new >= fdp->fd_nfiles) { > We either expand a descriptor table > [snip] > } else { > Or reuse existing descriptor, closing file if it's opened. > (void) fdrelease(p, new); > Which is the blocking operation, BTW. > } > return (finishdup(fdp, old, new, retval)); > } > [snip] > finishdup(fdp, old, new, retval) > register struct filedesc *fdp; > register int old, new; > register_t *retval; > { > register struct file *fp; > > fp = fdp->fd_ofiles[old]; > Got the struct sile of the file we are trying to dup... > if (fp->f_count == LONG_MAX-2) > ... and dereference it. We had checked that it's non-NULL, right? > > Wrong. Another thread might be sharing our descriptor table (man rfork). > IOW, fdp points to shared data structure. So we had done the equivalent of > > if (global_var) { > blocking_call(); > if (global_var->f_count) > ... > } > > Sloppy? Yes, and way beyond that. We have a nice shiny race between > dup2(0,1); and close(0). And it's a wide one. Turning that into > full-blown exploit is left as an exercise for readers. > > Example 2: > pipe() vs. close() (kern/sys_pipe.c) > > sys_opipe(p, v, retval) > [snip] > error = falloc(p, &rf, &fd); > if (error) > goto free2; > [snip] > retval[0] = fd; > > error = falloc(p, &wf, &fd); > if (error) > goto free3; > [snip] > return (0); > free3: > ffree(rf); > fdremove(fdp, retval[0]); > free2: > [snip] > > Think what happens if the second allocation fails. It is a > blocking call. During that time another thread had a nice possibility > to call close(retval[0]); since that value is very easy to predict - > it's the first available file descriptor. close() would > * remove pointer from fdp[retval[0]] > * call ffree() on it. > Now, we come back and do _another_ ffree() on the poor beast. Welcome to > kernel panic... > > Code is equivalent to > > global_var = p = alloc_foo(); > blocking_call(); > release_foo(p); > global_var = NULL; > > It's not just sloppy. It's obviously broken - obviously for anyone with > half of clue. > > I can easily provide more examples of the same crap and so can anyone > who would bother to RTFS the descriptor handling in kern/*. Apparently > that had never happened during the last 5 years or so. > > I'm not talking about the bugs that would require anything nontrivial to > find and understand. Just follow the yello^Wpiles of sloppy C and nearly > every one will turn out to be exploitable. And no, it's not limited to > descriptor handling - same goes for sys_pipe.c, etc. > > Theo had been informed about that crap. Couple of weeks ago. Finding and > fixing these bugs is a simple matter of grep. So far it hadn't been done. > I've proposed to help with that, but apparently it got no interest. <shrug> > Very well, there are other piles of garbage in need of fixing and seeing > crappy code in obscure Linux drivers is less disturbing than that in core > kernel. > > Frankly. my respect to Theo went way down. This code had never been read > through, let alone audited. And that's the core kernel. Moreover, the > same bugs had been fixed in FreeBSD half a year ago. In other words, just > keeping an eye on other *BSD trees would be enough to catch them. Same > for lurking on freebsd-hackers. Same for watching the Linux tree, where > an audit of relevant areas had been done nearly two years ago. Done and > discussed on linux-kernel. Sad... > > #include <stdrants/people_dont_bother_to_RTFS.h> > > -- > "You're one of those condescending Unix computer users!" > "Here's a nickel, kid. Get yourself a better computer" - Dilbert. > > ----- End forwarded message ----- -- -Alfred Perlstein [alfred@freebsd.org] Ok, who wrote this damn function called '??'? And why do my programs keep crashing in it? To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-fs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010724003654.B68587>