From owner-freebsd-security Fri Jul 20 0: 1:30 2001 Delivered-To: freebsd-security@freebsd.org Received: from whale.sunbay.crimea.ua (whale.sunbay.crimea.ua [212.110.138.65]) by hub.freebsd.org (Postfix) with ESMTP id B6DED37B401; Fri, 20 Jul 2001 00:01:06 -0700 (PDT) (envelope-from ru@whale.sunbay.crimea.ua) Received: (from ru@localhost) by whale.sunbay.crimea.ua (8.11.2/8.11.2) id f6K70T232105; Fri, 20 Jul 2001 10:00:29 +0300 (EEST) (envelope-from ru) Date: Fri, 20 Jul 2001 10:00:29 +0300 From: Ruslan Ermilov To: Matt Dillon Cc: Assar Westerlund , security@FreeBSD.ORG Subject: Re: [PATCH] Re: FreeBSD remote root exploit ? Message-ID: <20010720100029.A30828@sunbay.com> Mail-Followup-To: Matt Dillon , Assar Westerlund , security@FreeBSD.ORG References: <5.1.0.14.0.20010719001357.03e22638@192.168.0.12> <014d01c11031$bdab5a10$2001a8c0@clitoris> <20010719201407.B61061@sunbay.com> <003701c11077$b3125400$0d00a8c0@alexus> <3B5718A0.2B650C9C@oksala.org> <200107191752.f6JHqer75736@earth.backplane.com> <20010719205948.D67829@sunbay.com> <200107191817.f6JIHSJ76262@earth.backplane.com> <20010719215957.A74024@sunbay.com> <200107191917.f6JJHwV77405@earth.backplane.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="Dxnq1zWXvFF0Q93v" Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <200107191917.f6JJHwV77405@earth.backplane.com>; from dillon@earth.backplane.com on Thu, Jul 19, 2001 at 12:17:58PM -0700 Sender: owner-freebsd-security@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org --Dxnq1zWXvFF0Q93v Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Thu, Jul 19, 2001 at 12:17:58PM -0700, Matt Dillon wrote: > > :> > :> The output_data() calls for the various options are safe, strlen(format) > :> will always be larger then the actual formatted result. But the > :> debugging and crypto calls to output_data() are not safe. > :> > :> -Matt > :> > :> : netflush(); > :> : remaining = BUFSIZ - (nfrontp - netobuf); > :> : } > :> : ret = vsnprintf(nfrontp, remaining, format, args); > :> > :Should be fixed in state.c,v 1.7. Thanks, Assar! > : > : > :Cheers, > :-- > :Ruslan Ermilov Oracle Developer/DBA, > :ru@sunbay.com Sunbay Software AG, > > heh heh. Sorry guys, state.c still isn't quite right. > > nfrontp += ((ret < remaining - 1) ? ret : remaining - 1); > > What happens if remaining is 0 ? > Umm, let's count. 0. Let netobuf be 0. 1. nfrontp = BUFSIZ - 3 2. remaining = 3 and we try to write 10 bytes. 3. ret = 10 4. (10 < 3 - 1) ? 10 : 3 - 1 = 2 5. nfrontp += 2 = BUFSIZ - 1 [next 10 bytes write] 6. remaining = BUFSIZ - (BUFSIZ - 1) = 1 7. ret = 10 8. (10 < 1 - 1) ? 10 : 1 - 1 = 0 9. nfrontp += 0 = BUFSIZ - 1 remaining = BUFSIZ - (nfrontp - netobuf) = BUFSIZ - ((BUFSIZ - 1) - 0) = 1 So, the minimum possible value for `remaining' is 1. OTOH, we have another routine that advances nfrontp(): : int : output_datalen(const char *buf, size_t len) : { : size_t remaining; : : remaining = BUFSIZ - (nfrontp - netobuf); : if (remaining < len) { : netflush(); : remaining = BUFSIZ - (nfrontp - netobuf); : } : if (remaining < len) : return -1; : memmove(nfrontp, buf, len); : nfrontp += len; : return (len); : } 1. nfrontp = BUFSIZ - 3 2. remaining = 3 and we write len = 3 bytes. 3. nfrontp += 3 = BUFSIZ Then, on the next call to output_data() 4. remaining = 0 and, assuming that netflush() did nothing(!) 5. ret = 10 (10 bytes write attempt) 6. (10 < 0 - 1) ? 10 : 0 - 1 = -1 7. nfrontp += -1 = nfrontp - 1 So, the worst we can have `nfrontp' decremented by one. Not overflowable, but not right. OK, how about the following? It should be OK if `nfrontp' points beyond one byte of `netobuf'. See netflush() for details. Please review. Cheers, -- Ruslan Ermilov Oracle Developer/DBA, ru@sunbay.com Sunbay Software AG, ru@FreeBSD.org FreeBSD committer, +380.652.512.251 Simferopol, Ukraine http://www.FreeBSD.org The Power To Serve http://www.oracle.com Enabling The Information Age --Dxnq1zWXvFF0Q93v Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=p Index: ext.h =================================================================== RCS file: /home/ncvs/src/crypto/telnet/telnetd/ext.h,v retrieving revision 1.5 diff -u -p -r1.5 ext.h --- ext.h 2001/07/19 17:48:57 1.5 +++ ext.h 2001/07/20 06:50:28 @@ -74,7 +74,7 @@ extern char ptyobuf[BUFSIZ+NETSLOP], *pf extern char netibuf[BUFSIZ], *netip; -extern char netobuf[BUFSIZ+NETSLOP], *nfrontp, *nbackp; +extern char netobuf[BUFSIZ], *nfrontp, *nbackp; extern char *neturg; /* one past last bye of urgent data */ extern int pcc, ncc; Index: state.c =================================================================== RCS file: /home/ncvs/src/crypto/telnet/telnetd/state.c,v retrieving revision 1.7 diff -u -p -r1.7 state.c --- state.c 2001/07/19 18:58:31 1.7 +++ state.c 2001/07/20 06:51:13 @@ -1631,7 +1631,7 @@ output_data(const char *format, ...) remaining = BUFSIZ - (nfrontp - netobuf); } ret = vsnprintf(nfrontp, remaining, format, args); - nfrontp += ((ret < remaining - 1) ? ret : remaining - 1); + nfrontp += (ret < remaining) ? ret : remaining; va_end(args); return ret; } --Dxnq1zWXvFF0Q93v-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-security" in the body of the message