Date: Sun, 22 Jul 2001 22:14:14 -0700 From: Kris Kennaway <kris@obsecurity.org> To: Kris Kennaway <kris@obsecurity.org> Cc: Assar Westerlund <assar@FreeBSD.ORG>, Matt Dillon <dillon@earth.backplane.com>, Ruslan Ermilov <ru@FreeBSD.ORG>, audit@FreeBSD.ORG Subject: Re: [PATCH] Re: FreeBSD remote root exploit ? Message-ID: <20010722221413.A95414@xor.obsecurity.org> In-Reply-To: <20010722215619.A94874@xor.obsecurity.org>; from kris@obsecurity.org on Sun, Jul 22, 2001 at 09:56:20PM -0700 References: <200107191817.f6JIHSJ76262@earth.backplane.com> <20010719215957.A74024@sunbay.com> <200107191917.f6JJHwV77405@earth.backplane.com> <20010720100029.A30828@sunbay.com> <200107200932.f6K9WgZ88552@earth.backplane.com> <20010720143742.E65677@sunbay.com> <200107201717.f6KHHGa91142@earth.backplane.com> <20010722194031.A92249@jail-3.5> <5l66ck9wm7.fsf@assaris.sics.se> <20010722215619.A94874@xor.obsecurity.org>
next in thread | previous in thread | raw e-mail | index | archive | help
--qDbXVdCdHGoSgWSk Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Sun, Jul 22, 2001 at 09:56:20PM -0700, Kris Kennaway wrote: > * Some places which called netflush() conditionally (e.g. if there is > insufficient free space for the operation they're about to do) now > use while() to guarantee this; previously they could overflow if the > netflush() failed. Some of the netflush() calls seemed to only be > 'advisory' and nothing depends on the flush actually taking place > immediately. I've left these alone for now; perhaps they should be > changed to flush the entire buffer. After thinking about this a bit further, I've decided to make the standalone netflush() calls flush the entire buffer. This seems like a better thing to do than to potentially do nothing at all. I'm also not sure if I diffed the last patch against the correct CVS versions. Updated patch follows. Kris Index: ext.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /mnt/ncvs/src/crypto/telnet/telnetd/ext.h,v retrieving revision 1.2.8.2 diff -u -r1.2.8.2 ext.h --- ext.h 2001/07/20 15:16:52 1.2.8.2 +++ ext.h 2001/07/23 05:05:23 @@ -120,7 +120,6 @@ localstat P((void)), flowstat P((void)), netclear P((void)), - netflush P((void)), #ifdef DIAGNOSTICS printoption P((char *, int)), printdata P((char *, char *, int)), @@ -159,6 +158,7 @@ getpty P((int *)), #endif login_tty P((int)), + netflush P((void)), spcset P((int, cc_t *, cc_t **)), stilloob P((int)), terminit P((void)), Index: slc.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /mnt/ncvs/src/crypto/telnet/telnetd/slc.c,v retrieving revision 1.4.2.1 diff -u -r1.4.2.1 slc.c --- slc.c 2001/07/20 15:16:52 1.4.2.1 +++ slc.c 2001/07/23 05:09:10 @@ -176,7 +176,6 @@ register unsigned char **bufp; { register int len; - void netflush(); =20 /* * If a change has occured, store the new terminal control @@ -205,7 +204,8 @@ slcptr +=3D 2; len =3D slcptr - slcbuf; output_datalen(slcbuf, len); - netflush(); /* force it out immediately */ + while ((nfrontp - nbackp) > 0) + netflush(); /* force it out immediately */ DIAG(TD_OPTIONS, printsub('>', slcbuf+2, len-2);); } } Index: state.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /mnt/ncvs/src/crypto/telnet/telnetd/state.c,v retrieving revision 1.4.2.1 diff -u -r1.4.2.1 state.c --- state.c 2001/07/20 15:16:52 1.4.2.1 +++ state.c 2001/07/23 05:11:24 @@ -938,7 +938,8 @@ set_my_want_state_will(TELOPT_LOGOUT); send_will(TELOPT_LOGOUT, 0); set_my_state_will(TELOPT_LOGOUT); - (void)netflush(); + while ((nfrontp - nbackp) > 0) + netflush(); cleanup(0); /* NOT REACHED */ break; @@ -1100,7 +1101,8 @@ { register int subchar; =20 - DIAG(TD_OPTIONS, {netflush(); printsub('<', subpointer, SB_LEN()+2);}); + DIAG(TD_OPTIONS, {while ((nfrontp - nbackp) > 0) netflush(); + printsub('<', subpointer, SB_LEN()+2);}); =20 subchar =3D SB_GET(); switch (subchar) { @@ -1532,7 +1534,8 @@ =20 ncp =3D statusbuf; =20 - netflush(); /* get rid of anything waiting to go out */ + while ((nfrontp - nbackp) > 0) + netflush(); /* get rid of anything waiting to go out */ =20 ADD(IAC); ADD(SB); @@ -1607,48 +1610,79 @@ ADD(SE); =20 output_datalen(statusbuf, ncp - statusbuf); - netflush(); /* Send it on its way */ + while ((nfrontp - nbackp) > 0) + netflush(); /* Send it on its way */ =20 DIAG(TD_OPTIONS, - {printsub('>', statusbuf, ncp - statusbuf); netflush();}); + {printsub('>', statusbuf, ncp - statusbuf); + while ((nfrontp - nbackp) > 0) netflush();}); } =20 /* * This function appends data to nfrontp and advances nfrontp. + * Returns the number of characters written altogether (the buffer may have + * been flushed in the process). */ =20 int output_data(const char *format, ...) { va_list args; - size_t remaining, ret; + size_t remaining, copied; + int bufremain; + char *buf, *bufp; =20 va_start(args, format); + /* calculate free space to play with */ remaining =3D BUFSIZ - (nfrontp - netobuf); - /* try a netflush() if the room is too low */ - if (strlen(format) > remaining || BUFSIZ / 4 > remaining) { - netflush(); - remaining =3D BUFSIZ - (nfrontp - netobuf); + + if ((bufremain =3D vasprintf(&buf, format, args)) =3D=3D -1) + return -1; + bufp =3D buf; + + while (bufremain > 0) { + /* Free up enough space if the room is too low */ + while ((bufremain > BUFSIZ ? BUFSIZ : bufremain) > remaining) + remaining +=3D netflush(); + + /* Copy out as much as will fit */ + copied =3D remaining > bufremain ? bufremain : remaining; + memmove(nfrontp, bufp, copied); + nfrontp +=3D copied; + bufremain -=3D copied; + remaining -=3D copied; + bufp +=3D copied; } - ret =3D vsnprintf(nfrontp, remaining, format, args); - nfrontp +=3D (ret < remaining) ? ret : remaining; va_end(args); - return ret; + bufremain =3D strlen(buf); + free(buf); + return bufremain; } =20 int output_datalen(const char *buf, size_t len) { size_t remaining; - + int bufremain, copied; + const char *bufp; +=09 remaining =3D BUFSIZ - (nfrontp - netobuf); - if (remaining < len) { - netflush(); - remaining =3D BUFSIZ - (nfrontp - netobuf); - if (remaining < len) - return -1; + bufremain =3D len; + bufp =3D buf; + + while (bufremain > 0) { + /* Free up enough space if the room is too low*/ + while((bufremain > BUFSIZ ? BUFSIZ : bufremain) > remaining) + remaining +=3D netflush(); + + /* Copy out as much as will fit */ + copied =3D remaining > bufremain ? bufremain : remaining; + memmove(nfrontp, bufp, copied); + nfrontp +=3D copied; + bufremain -=3D copied; + remaining -=3D copied; + bufp +=3D copied; } - memmove(nfrontp, buf, len); - nfrontp +=3D len; + return (len); } Index: telnetd.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /mnt/ncvs/src/crypto/telnet/telnetd/telnetd.c,v retrieving revision 1.11.2.3 diff -u -r1.11.2.3 telnetd.c --- telnetd.c 2001/07/20 15:16:52 1.11.2.3 +++ telnetd.c 2001/07/23 05:05:23 @@ -952,7 +952,6 @@ char *HE; char *HN; char *IM; - void netflush(); int nfd; =20 /* @@ -1420,8 +1419,9 @@ } #endif /* defined(CRAY2) && defined(UNICOS5) */ =20 - if (FD_ISSET(f, &obits) && (nfrontp - nbackp) > 0) - netflush(); + if (FD_ISSET(f, &obits)) + while ((nfrontp - nbackp) > 0) + netflush(); if (ncc > 0) telrcv(); if (FD_ISSET(p, &obits) && (pfrontp - pbackp) > 0) Index: termstat.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /mnt/ncvs/src/crypto/telnet/telnetd/termstat.c,v retrieving revision 1.4.2.2 diff -u -r1.4.2.2 termstat.c --- termstat.c 2001/07/20 15:16:52 1.4.2.2 +++ termstat.c 2001/07/23 05:05:24 @@ -140,7 +140,6 @@ void localstat() { - void netflush(); int need_will_echo =3D 0; =20 #if defined(CRAY2) && defined(UNICOS5) @@ -404,7 +403,6 @@ clientstat(code, parm1, parm2) register int code, parm1, parm2; { - void netflush(); =20 /* * Get a copy of terminal characteristics. Index: utility.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /mnt/ncvs/src/crypto/telnet/telnetd/utility.c,v retrieving revision 1.5.2.2 diff -u -r1.5.2.2 utility.c --- utility.c 2001/07/20 15:16:52 1.5.2.2 +++ utility.c 2001/07/23 05:05:24 @@ -69,10 +69,9 @@ void ttloop() { - void netflush(); =20 DIAG(TD_REPORT, output_data("td: ttloop\r\n")); - if (nfrontp-nbackp) { + while ((nfrontp - nbackp) > 0) { netflush(); } ncc =3D read(net, netibuf, sizeof netibuf); @@ -249,18 +248,22 @@ /* * netflush * Send as much data as possible to the network, - * handling requests for urgent data. + * handling requests for urgent data. Not all data in the + * buffer may be sent. */ - void + int netflush() { int n; extern int not42; =20 if ((n =3D nfrontp - nbackp) > 0) { +#if 0 + /* XXX This causes output_data() to recurse and die */ DIAG(TD_REPORT, { n +=3D output_data("td: netflush %d chars\r\n", n); }); +#endif #ifdef ENCRYPTION if (encrypt_output) { char *s =3D nclearto ? nclearto : nbackp; @@ -296,7 +299,7 @@ } if (n < 0) { if (errno =3D=3D EWOULDBLOCK || errno =3D=3D EINTR) - return; + return 0; cleanup(0); } nbackp +=3D n; @@ -313,7 +316,7 @@ nclearto =3D 0; #endif /* ENCRYPTION */ } - return; + return (n); } /* end of netflush */ =20 =20 @@ -1082,7 +1085,7 @@ =20 while (cnt) { /* flush net output buffer if no room for new data) */ - if ((&netobuf[BUFSIZ] - nfrontp) < 80) { + while ((&netobuf[BUFSIZ] - nfrontp) < 80) { netflush(); } =20 --qDbXVdCdHGoSgWSk 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 iD8DBQE7W7KlWry0BWjoQKURAt/7AJ0ahHx2P4erlF66H7PvjUyikErkUwCg706O M81Bq7cl29EHaBtQDK7TlEs= =1gGv -----END PGP SIGNATURE----- --qDbXVdCdHGoSgWSk-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010722221413.A95414>