bin/50749: ipfw2 incorrectly parses ports and port ranges

Dmitry Karasik dmitry at karasik.eu.org
Wed Apr 9 03:00:34 PDT 2003


>Number:         50749
>Category:       bin
>Synopsis:       ipfw2 incorrectly parses ports and port ranges
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Apr 09 03:00:32 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator:     Dmitry Karasik
>Release:        FreeBSD 4.8-STABLE i386
>Organization:
>Environment:
System: FreeBSD raven.plab.ku.dk 4.8-STABLE FreeBSD 4.8-STABLE #7: Mon Apr 7 13:56:46 CEST 2003 root at raven.plab.ku.dk:/usr/obj/usr/src/sys/RAVEN i386


	
>Description:

        ipfw2 ( ipfw compiled with -DIPFW2) allows multiple port ranges in a single
        rule, but parses these incorrectly. Moreover, when ipfw2 fails to parse a
        port, the port list prosessing silently stops and no error is reported.

>How-To-Repeat:

        Example: valid port name 'ftp-data' is treated incorrectly and 
                 ports 'ssh' and 'www' are silently skipped:

           Input:  ipfw add 1000 allow tcp from any to any ftp,ftp-data,ssh,www
           Output: 1000 allow tcp from any to any dst-port 21

>Fix:

	Patch to /usr/src/sbin/ipfw/ipfw2.c resolves the problem. It is based
        on a comment in ipfw2.c that states that only numeric ranges are 
        allowed. Thus, the ports ranges like 'ftp-data-30' and 'ssh-25' are 
        treated as invalid. The reverse ranges, like '225-ssh', are still valid
        though.

--- ipfw2.c.patch begins here ---
--- ipfw2.c	Wed Apr  9 11:27:10 2003
+++ /plab.ku.dk/usr/src/sbin/ipfw/ipfw2.c	Wed Apr  9 11:26:12 2003
@@ -451,7 +451,7 @@
 	/*
 	 * find separator. '\\' escapes the next char.
 	 */
-	for (s1 = s; *s1 && (isalnum(*s1) || *s1 == '\\') ; s1++)
+	for (s1 = s; *s1 && (isalnum(*s1) || *s1 == '\\' || *s1 == '-') ; s1++)
 		if (*s1 == '\\' && s1[1] != '\0')
 			s1++;
 
@@ -499,20 +499,29 @@
 fill_newports(ipfw_insn_u16 *cmd, char *av, int proto)
 {
 	u_int16_t *p = cmd->ports;
-	int i = 0;
-	char *s = av;
+	int i = 0, ignore_first_error = 1;
+	char *s = av, *s1;
 
 	while (*s) {
 		u_int16_t a, b;
 
+		s1 = s;
 		a = strtoport(av, &s, 0, proto);
-		if (s == av) /* no parameter */
+		if (s == av) {/* no parameter */
+		   	if ( !ignore_first_error) { 
+			   	if ( *s1 == ',') *s1++;
+				errx(EX_DATAERR,
+				    "illegal port ``%s''", s1);
+			}
 			break;
+		}
+		ignore_first_error = 0;
 		if (*s == '-') { /* a range */
 			av = s+1;
 			b = strtoport(av, &s, 0, proto);
 			if (s == av) /* no parameter */
-				break;
+				errx(EX_DATAERR,
+			    		"illegal port ``%s''", s);
 			p[0] = a;
 			p[1] = b;
 		} else if (*s == ',' || *s == '\0' ) {
--- ipfw2.c.patch ends here ---


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


More information about the freebsd-bugs mailing list