From owner-freebsd-security Wed Dec 23 13:12:24 1998 Return-Path: <owner-freebsd-security@FreeBSD.ORG> Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id NAA08677 for freebsd-security-outgoing; Wed, 23 Dec 1998 13:12:24 -0800 (PST) (envelope-from owner-freebsd-security@FreeBSD.ORG) Received: from apollo.backplane.com (apollo.backplane.com [209.157.86.2]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id NAA08671 for <freebsd-security@FreeBSD.ORG>; Wed, 23 Dec 1998 13:12:20 -0800 (PST) (envelope-from dillon@apollo.backplane.com) Received: (from dillon@localhost) by apollo.backplane.com (8.9.1/8.9.1) id NAA17044; Wed, 23 Dec 1998 13:12:14 -0800 (PST) (envelope-from dillon) Date: Wed, 23 Dec 1998 13:12:14 -0800 (PST) From: Matthew Dillon <dillon@apollo.backplane.com> Message-Id: <199812232112.NAA17044@apollo.backplane.com> To: Matthew Dillon <dillon@apollo.backplane.com> Cc: Peter Jeremy <peter.jeremy@auss2.alcatel.com.au>, freebsd-security@FreeBSD.ORG Subject: Re: cvs commit: src/etc rc.conf Sender: owner-freebsd-security@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org Ok, I've looked at it some more. It isn't as bad as I thought but it is still pretty bad. Here's the problem: process A: make unix domain connection sendmsg a couple of file descriptors close the descriptors we just sent close the connection (unc_gc() runs at this point and tries to flush/close these descriptors, but doesn't quite do it right. However, I looked all the way back to the 4.4 lite commit and it does not appear to gatuitously close the descriptors. Instead, it relies on sorflush() to do that). process B: create socket, listen on socket. wait until A has made the connection, sent the descriptors, and closed its connection. accept() the connection from A (which is now closed on A's) side. recvmsg() descriptors, which were previously closed but may now be valid again and hold references to files used by other processes if we have waited a sufficient period of time. However, from my reading of the code if these descriptors had been closed, the associated socket buffer would have been flushed so this can't happen. Ok, and this is why it *DOESN'T* actually happen: unc_gc() adds an f_count reference, then attempt to sorflush() the isolated files, then closes them (subtracting one from the ref count). Thus it is left up to sorflush() to actually close the descriptors. sorflush() will release the associated messages so we should be safe. But here's the problem: unp_gc() is confused. It is calling sorflush() on non-sockets. Line 1118 of kern/uipc_usrreq.c: /* * for each FD on our hit list, do the following two things */ for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) sorflush((struct socket *)(*fpp)->f_data); <------- for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) closef(*fpp, (struct proc *) NULL); free((caddr_t)extra_ref, M_FILE); unp_gcing = 0; It happily believes that any descriptor for which FMARK has not been set is not marked accessible and thus, somehow, is magically a socket and calls sorflush() on it. But the descriptors that were queued in those sendmsg()'s wind up not being FMARK's because their f_count == f_msgcount. unp_gc() then assumes these descriptors are unix domain sockets. But they are not necessarily unix domain sockets. Could someone take a look at that and tell me if I am right in regards to the sorflush() ? ::At the bottom of page 389: :: "If a listening socket is accessible, then any queued connections :: that it holds are also accessible; the garbage collector in 4.4BSD :: fails to take this into account." :: ::This footnote is referenced from a paragraph discussing unp_gc() - ::which can be found in kern/uipc_usrreq.c. From a quick look at the ::2.2.6 CVS logs (the latest I can quickly study), it doesn't look like ::it's ever been eradicated. :: ::Peter : : Shit. There's a bug. It took me a while to find it, but there's a : bug. A very bad bug. A Very, very, very, very bad bug. I'm going to : fix this in the FreeBSD tree first, then post the diff without : additional comment. : : -Matt Matthew Dillon Engineering, HiWay Technologies, Inc. & BEST Internet Communications & God knows what else. <dillon@backplane.com> (Please include original email in any response) To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-security" in the body of the message