From owner-freebsd-security Mon May 10 7: 6:23 1999 Delivered-To: freebsd-security@freebsd.org Received: from gatekeeper.tsc.tdk.com (gatekeeper.tsc.tdk.com [207.113.159.21]) by hub.freebsd.org (Postfix) with ESMTP id 832E4152E5 for ; Mon, 10 May 1999 07:06:17 -0700 (PDT) (envelope-from gdonl@tsc.tdk.com) Received: from sunrise.gv.tsc.tdk.com (root@sunrise.gv.tsc.tdk.com [192.168.241.191]) by gatekeeper.tsc.tdk.com (8.8.8/8.8.8) with ESMTP id HAA21502; Mon, 10 May 1999 07:06:09 -0700 (PDT) (envelope-from gdonl@tsc.tdk.com) Received: from salsa.gv.tsc.tdk.com (salsa.gv.tsc.tdk.com [192.168.241.194]) by sunrise.gv.tsc.tdk.com (8.8.5/8.8.5) with ESMTP id HAA20080; Mon, 10 May 1999 07:06:08 -0700 (PDT) Received: (from gdonl@localhost) by salsa.gv.tsc.tdk.com (8.8.5/8.8.5) id HAA23383; Mon, 10 May 1999 07:06:06 -0700 (PDT) From: Don Lewis Message-Id: <199905101406.HAA23383@salsa.gv.tsc.tdk.com> Date: Mon, 10 May 1999 07:06:05 -0700 In-Reply-To: Don Lewis "Re: KKIS.05051999.003b" (May 9, 5:40am) X-Mailer: Mail User's Shell (7.2.6 alpha(3) 7/19/95) To: Don Lewis , Wes Peters Subject: Re: KKIS.05051999.003b Cc: Kevin Day , security@FreeBSD.ORG Sender: owner-freebsd-security@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org On May 9, 5:40am, Don Lewis wrote: } Subject: Re: KKIS.05051999.003b } On May 8, 10:21pm, Wes Peters wrote: } } Subject: Re: KKIS.05051999.003b } } Don Lewis wrote: } } } > I don't see any obvious descriptor leaks, but the fact that FreeBSD < 3.1 } } > panics (probably in unp_gc(), which Matt fixed) indicates that I'm missing } } > something. The exploit code should not result in any calls to unp_gc(), } } > because the client receives all the descriptors that are sent by the server. } } } } Actually it doesn't. If you look up the first message I posted on this } } subject, I listed the error messages it produces, many of which indicated } } the client didn't get a descriptor from the server IIRC. ] On my 3.1-RELEASE system it reports numerous sendmsg ECONNREFUSED and ] ENOENTs, then eventually dives into repeats of: ] ] unlink error 2 ] bind error 9 ] sento error 9 ] recvmsg error 9 ] socket error 23 Steinar Haug noticed something odd in the exploit code - the client process doesn't block in recvmsg() like one would expect. If a message is waiting, the client process will receive it, but if not, the client will fall through the recvmsg() without getting an error indication. This means that the client and server don't run in lockstep. With the default UFS mount options for /tmp, the client process will block for short periods of time while it executes bind() and unlink(). If /tmp is MFS or is mounted async or with softupdates, the client process will probably only block when its scheduling quantum expires. This oddity may allow multiple requests to accumulate for the server process, and allows the server process to attempt to send responses at possibly inconvenient times for the client. If the server calls sendmsg() between the client's bind() and recvmsg() syscalls, then everything works normally. If the server calls sendmsg() between the client's recvmsg() and close(sockfd) syscalls, or if the server manages to do more than one sendmsg() call during one iteration of the client, which might happen if the client exhausts its scheduling time quantum, one or more messages will be outstanding when the client executes close(sockfd). This will result in unp_gc() being called to garbage collect the descriptors that are in flight. In FreeBSD < 3.1-RELEASE, this will result in a panic due to sorflush() being improperly called on a non-socket descriptor. If the server calls sendmsg() after the client's close(sockfd) and before the client unlinks the socket, the sendmsg() call will fail with ECONNREFUSED. If the server calls sendmsg() after the client unlinks the socket and before the client calls bind(), then the sendmsg() will fail with ENOENT. Either of these failures will cause the descriptor being sent to be permanently leaked away. The rate at which descriptors are leaked depends on how the client and server processes are scheduled. Once enough descriptors have been leaked away, the client's socket() syscall will fail with ENFILE, the bind(), sendto(), and recvmsg() syscalls will fail with EBADF because the socket was not created, and unlink() will fail because the socket name was not created by bind(). The following patch appears to fix the descriptor leak. I hope to commit it later today. Index: uipc_usrreq.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_usrreq.c,v retrieving revision 1.43 diff -u -u -r1.43 uipc_usrreq.c --- uipc_usrreq.c 1999/04/28 11:37:07 1.43 +++ uipc_usrreq.c 1999/05/09 23:50:45 @@ -367,6 +367,9 @@ unp_shutdown(unp); } + if (control && error != 0) + unp_dispose(control); + release: if (control) m_freem(control); To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-security" in the body of the message