[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: Locally exploitable races in OpenBSD VFS (fwd)
The relevant people have probably seen it, but is there a fix?
: -----Original Message-----
: From: Alexander Viro [mailto:viro@math.psu.edu]
: Sent: Saturday, June 02, 2001 7:00 PM
: To: BUGTRAQ@SECURITYFOCUS.COM
: Subject: Locally exploitable races in OpenBSD VFS
:
:
: [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.
: