summaryrefslogtreecommitdiffstats
path: root/contrib/telnet/telnetd/state.c
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2001-07-19 17:48:57 +0000
committerru <ru@FreeBSD.org>2001-07-19 17:48:57 +0000
commit9cac33d71fc5f6846362da63a753c08e90efa427 (patch)
treebe1f96775e90a28babf09a5748699e16c80568d6 /contrib/telnet/telnetd/state.c
parent32934481938551563374cb61f766b1f332377ee6 (diff)
downloadFreeBSD-src-9cac33d71fc5f6846362da63a753c08e90efa427.zip
FreeBSD-src-9cac33d71fc5f6846362da63a753c08e90efa427.tar.gz
Fixed the exploitable remote buffer overflow.
Reported on: bugtraq Obtained from: Heimdal, NetBSD Reviewed by: obrien, imp
Diffstat (limited to 'contrib/telnet/telnetd/state.c')
-rw-r--r--contrib/telnet/telnetd/state.c61
1 files changed, 48 insertions, 13 deletions
diff --git a/contrib/telnet/telnetd/state.c b/contrib/telnet/telnetd/state.c
index 4a066b7..ec012cf 100644
--- a/contrib/telnet/telnetd/state.c
+++ b/contrib/telnet/telnetd/state.c
@@ -39,6 +39,7 @@ static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
+#include <stdarg.h>
#include "telnetd.h"
#if defined(AUTHENTICATION)
#include <libtelnet/auth.h>
@@ -205,8 +206,7 @@ gotiac: switch (c) {
}
netclear(); /* clear buffer back */
- *nfrontp++ = IAC;
- *nfrontp++ = DM;
+ output_data("%c%c", IAC, DM);
neturg = nfrontp-1; /* off by one XXX */
DIAG(TD_OPTIONS,
printoption("td: send IAC", DM));
@@ -459,8 +459,7 @@ send_do(option, init)
set_his_want_state_will(option);
do_dont_resp[option]++;
}
- (void) sprintf(nfrontp, (char *)doopt, option);
- nfrontp += sizeof (dont) - 2;
+ output_data((const char *)doopt, option);
DIAG(TD_OPTIONS, printoption("td: send do", option));
}
@@ -679,8 +678,7 @@ send_dont(option, init)
set_his_want_state_wont(option);
do_dont_resp[option]++;
}
- (void) sprintf(nfrontp, (char *)dont, option);
- nfrontp += sizeof (doopt) - 2;
+ output_data((const char *)dont, option);
DIAG(TD_OPTIONS, printoption("td: send dont", option));
}
@@ -828,8 +826,7 @@ send_will(option, init)
set_my_want_state_will(option);
will_wont_resp[option]++;
}
- (void) sprintf(nfrontp, (char *)will, option);
- nfrontp += sizeof (doopt) - 2;
+ output_data((const char *)will, option);
DIAG(TD_OPTIONS, printoption("td: send will", option));
}
@@ -987,8 +984,7 @@ send_wont(option, init)
set_my_want_state_wont(option);
will_wont_resp[option]++;
}
- (void) sprintf(nfrontp, (char *)wont, option);
- nfrontp += sizeof (wont) - 2;
+ output_data((const char *)wont, option);
DIAG(TD_OPTIONS, printoption("td: send wont", option));
}
@@ -1384,9 +1380,8 @@ suboption()
env_ovar_wrong:
env_ovar = OLD_ENV_VALUE;
env_ovalue = OLD_ENV_VAR;
- DIAG(TD_OPTIONS, {sprintf(nfrontp,
- "ENVIRON VALUE and VAR are reversed!\r\n");
- nfrontp += strlen(nfrontp);});
+ DIAG(TD_OPTIONS,
+ output_data("ENVIRON VALUE and VAR are reversed!\r\n"));
}
}
@@ -1617,3 +1612,43 @@ send_status()
DIAG(TD_OPTIONS,
{printsub('>', statusbuf, ncp - statusbuf); netflush();});
}
+
+/*
+ * This function appends data to nfrontp and advances nfrontp.
+ */
+
+int
+output_data(const char *format, ...)
+{
+ va_list args;
+ size_t remaining, ret;
+
+ va_start(args, format);
+ remaining = BUFSIZ - (nfrontp - netobuf);
+ /* try a netflush() if the room is too low */
+ if (strlen(format) > remaining || BUFSIZ / 4 > remaining) {
+ netflush();
+ remaining = BUFSIZ - (nfrontp - netobuf);
+ }
+ ret = vsnprintf(nfrontp, remaining, format, args);
+ nfrontp += ret;
+ va_end(args);
+ return ret;
+}
+
+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);
+}
OpenPOWER on IntegriCloud