Date: Fri, 20 Jul 2001 02:32:42 -0700 (PDT) From: Matt Dillon <dillon@earth.backplane.com> To: Ruslan Ermilov <ru@FreeBSD.ORG> Cc: Assar Westerlund <assar@FreeBSD.ORG>, security@FreeBSD.ORG Subject: Re: [PATCH] Re: FreeBSD remote root exploit ? Message-ID: <200107200932.f6K9WgZ88552@earth.backplane.com> 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> <20010720100029.A30828@sunbay.com>
next in thread | previous in thread | raw e-mail | index | archive | help
:..
:
: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.
Except on the NEXT call remaining will be negative, but
since remaining is unsigned it will appear to be a very
large number and the routine will believe that *any* length
is legal. Now, of course, the attempt to netflush() will
probably hide this potential problem but it is still a good
idea to write bullet proof code that does not rely on
caller assumptions.
: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,
The below fix seems reasonable. Strictly speaking it isn't really
pointing beyond the end of netobuf, the pointer will simply be such
that the length calculation will wind up being exactly the size of
netobuf which is what you want.
I would go further and just use 'int' instead of size_t in this
routine, and to doubly guarentee that no miscalculation will occur
you would assert() that remaining is >= 0 (in addition to the changes
you make below). It pays to write safe code.
-Matt
: 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200107200932.f6K9WgZ88552>
