bin/176278: /usr/bin/nc (netcat) incorrectly passes telnet option data through

Paul Koch paul.koch137 at gmail.com
Wed Feb 20 03:10:00 UTC 2013


>Number:         176278
>Category:       bin
>Synopsis:       /usr/bin/nc (netcat) incorrectly passes telnet option data through
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Feb 20 03:10:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator:     Paul Koch
>Release:        9.1
>Organization:
>Environment:
FreeBSD xxxxx 9.1-STABLE FreeBSD 9.1-STABLE #0 r246099: Thu Jan 31 08:47:47 EST 2013 
>Description:
Run /usr/bin/nc -t {ip} 23

Garbage characters appear in output.

Run /usr/bin/nc -t {ip 23 | hexdump -C

This will show something like the following at the start:

 ff fd 25 ff fb 26 ff fd ...

The ff fd xx are telnet options which should be stripped from the output.

Telnet options can occur pretty much at any time during the session, so
garbage chars will probably also appear in other places of the output.
>How-To-Repeat:
Run nc command as above.
>Fix:
The telnet command opt processing in netcat.c is fairly crude.
Strip the telnet options from the output buffer.



Patch attached with submission follows:

--- netcat.c	2013-02-20 12:46:17.000000000 +1000
+++ netcat.c.orig	2013-02-20 13:03:50.000000000 +1000
@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: stable/9/contrib/netcat/netcat.c 243818 2012-12-03 18:26:23Z delphij $
+ * $FreeBSD$
  */
 
 /*
@@ -100,7 +100,7 @@
 char *portlist[PORT_MAX+1];
 char *unix_dg_tmp_socket;
 
-int	atelnet(int, unsigned char *, unsigned int);
+void	atelnet(int, unsigned char *, unsigned int);
 void	build_ports(char *);
 void	help(void);
 int	local_listen(char *, char *, struct addrinfo);
@@ -823,7 +823,7 @@
 				pfd[0].events = 0;
 			} else {
 				if (tflag)
-					n = atelnet(nfd, buf, n);
+					atelnet(nfd, buf, n);
 				if (atomicio(vwrite, lfd, buf, n) != n)
 					return;
 			}
@@ -845,23 +845,20 @@
 }
 
 /* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */
-int
+void
 atelnet(int nfd, unsigned char *buf, unsigned int size)
 {
-	unsigned char *p, *q, *end;
+	unsigned char *p, *end;
 	unsigned char obuf[4];
-        int compact = 0;
 
 	if (size < 3)
-		return size;
+		return;
 	end = buf + size - 2;
 
 	for (p = buf; p < end; p++) {
 		if (*p != IAC)
 			continue;
 
-                compact = 1;
-
 		obuf[0] = IAC;
 		p++;
 		if ((*p == WILL) || (*p == WONT))
@@ -876,20 +873,6 @@
 		if (atomicio(vwrite, nfd, obuf, 3) != 3)
 			warn("Write Error!");
 	}
-
-        if (compact) {
-                p = q = buf;
-                end = buf + size;
-                while (p < end) {
-                        if (*p == IAC)
-                                p += 3;  /* skip over telnet opt */
-                        else
-                                *q++ = *p++;
-                }
-                size = q - buf;
-        }
-
-        return size;
 }
 
 /*


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list