--- telnet/telnet.c.orig 2005-03-30 09:17:58.000000000 -0300 +++ telnet/telnet.c 2005-03-30 10:09:47.000000000 -0300 @@ -1131,6 +1131,7 @@ unsigned char slc_reply[128]; +unsigned char const * const slc_reply_eom = &slc_reply[sizeof(slc_reply)]; unsigned char *slc_replyp; void @@ -1146,6 +1147,14 @@ void slc_add_reply(unsigned char func, unsigned char flags, cc_t value) { + /* A sequence of up to 6 bytes my be written for this member of the SLC + * suboption list by this function. The end of negotiation command, + * which is written by slc_end_reply(), will require 2 additional + * bytes. Do not proceed unless there is sufficient space for these + * items. + */ + if (&slc_replyp[6+2] > slc_reply_eom) + return; if ((*slc_replyp++ = func) == IAC) *slc_replyp++ = IAC; if ((*slc_replyp++ = flags) == IAC) @@ -1159,6 +1168,10 @@ { int len; + /* The end of negotiation command requires 2 bytes. */ + if (&slc_replyp[2] > slc_reply_eom) + return; + *slc_replyp++ = IAC; *slc_replyp++ = SE; len = slc_replyp - slc_reply; @@ -1236,8 +1249,8 @@ } } -#define OPT_REPLY_SIZE 256 -unsigned char *opt_reply; +#define OPT_REPLY_SIZE (2 * SUBBUFSIZE) +unsigned char *opt_reply = NULL; unsigned char *opt_replyp; unsigned char *opt_replyend; @@ -1298,8 +1311,8 @@ return; } vp = env_getvalue(ep); - if (opt_replyp + (vp ? strlen((char *)vp) : 0) + - strlen((char *)ep) + 6 > opt_replyend) + if (opt_replyp + (vp ? 2 * strlen((char *)vp) : 0) + + 2 * strlen((char *)ep) + 6 > opt_replyend) { int len; unsigned char *p; @@ -1323,6 +1336,8 @@ *opt_replyp++ = ENV_USERVAR; for (;;) { while ((c = *ep++)) { + if (opt_replyp + (2 + 2) > opt_replyend) + return; switch(c&0xff) { case IAC: *opt_replyp++ = IAC; @@ -1337,6 +1352,8 @@ *opt_replyp++ = c; } if ((ep = vp)) { + if (opt_replyp + (1 + 2 + 2) > opt_replyend) + return; *opt_replyp++ = ENV_VALUE; vp = NULL; } else @@ -1361,7 +1378,10 @@ { int len; - len = opt_replyp - opt_reply + 2; + if (opt_replyp + 2 > opt_replyend) + return; + len = opt_replyp + 2 - opt_reply; + if (emptyok || len > 6) { *opt_replyp++ = IAC; *opt_replyp++ = SE;