From owner-freebsd-fs Mon Jul 23 20:25:36 2001 Delivered-To: freebsd-fs@freebsd.org Received: from obsecurity.dyndns.org (adsl-63-207-60-215.dsl.lsan03.pacbell.net [63.207.60.215]) by hub.freebsd.org (Postfix) with ESMTP id 5724E37B403 for ; Mon, 23 Jul 2001 20:25:28 -0700 (PDT) (envelope-from kris@obsecurity.org) Received: by obsecurity.dyndns.org (Postfix, from userid 1000) id 9CD8A66B04; Mon, 23 Jul 2001 20:25:27 -0700 (PDT) Date: Mon, 23 Jul 2001 20:25:27 -0700 From: Kris Kennaway To: fs@FreeBSD.org Subject: [viro@math.psu.edu: Locally exploitable races in OpenBSD VFS] Message-ID: <20010723202526.B96630@xor.obsecurity.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-md5; protocol="application/pgp-signature"; boundary="7ZAtKRhVyVSsbBD2" Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-fs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org --7ZAtKRhVyVSsbBD2 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Has anyone looked at whether these apply to us? Kris ----- Forwarded message from Alexander Viro ----- Delivered-To: kkenn@localhost.obsecurity.org Date: Sat, 02 Jun 2001 19:00:08 -0400 (EDT) From: Alexander Viro 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: List-Post: List-Help: List-Unsubscribe: List-Subscribe: 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 >=3D fdp->fd_nfiles || fdp->fd_ofiles[old] =3D=3D NU= LL || (u_int)new >=3D p->p_rlimit[RLIMIT_NOFILE].rlim_cur || (u_int)new >=3D maxfiles) return (EBADF); OK, we've checked (among other things) that old is indeed opened. [snip] if (new >=3D 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 =3D fdp->fd_ofiles[old]; Got the struct sile of the file we are trying to dup... if (fp->f_count =3D=3D LONG_MAX-2) =2E.. 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 =3D falloc(p, &rf, &fd); if (error) goto free2; [snip] retval[0] =3D fd; error =3D 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 =3D p =3D alloc_foo(); blocking_call(); release_foo(p); global_var =3D 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. = =20 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 --=20 "You're one of those condescending Unix computer users!" "Here's a nickel, kid. Get yourself a better computer" - Dilbert. ----- End forwarded message ----- --7ZAtKRhVyVSsbBD2 Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6 (FreeBSD) Comment: For info see http://www.gnupg.org iD8DBQE7XOqmWry0BWjoQKURAut7AJ9ISEf9Pvv78XWl2V/A4AuYnjxAuwCgrgaj cAKVbKl2vn3umIeRNCe6SaI= =V/gp -----END PGP SIGNATURE----- --7ZAtKRhVyVSsbBD2-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-fs" in the body of the message