Subject: bin/8783: host(1) crashes due to bad commandline parsing
To: None <gnats-bugs@gnats.netbsd.org>
From: Aymeric Vincent <Aymeric.Vincent@crans.ens-cachan.fr>
List: netbsd-bugs
Date: 11/12/1999 11:50:03
>Number:         8783
>Category:       bin
>Synopsis:       host(1) crashes due to bad commandline parsing
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Nov 12 11:24:01 1999
>Last-Modified:
>Originator:     Aymeric Vincent
>Organization:
  student
>Release:        current-19991112
>Environment:
System: NetBSD ungnu 1.4L NetBSD 1.4L (SMALLY) #13: Sat Nov 6 12:14:40 CET 1999 stack@ungnu:/usr/src/sys/arch/i386/compile/SMALLY i386

>Description:
 host(1) dumps core when given certain erroneous numbers of arguments
>How-To-Repeat:
stack@ungnu[86]%        host -t MX
Segmentation fault (core dumped)
stack@ungnu[87]%

>Fix:

apply following diff to usr.sbin/bind/host/host.c
(changed a couple of things in main() to factor some code and added a usage()
static function to make things less prone to errors).

WARNING: this diff makes it `impossible' to lookup hosts starting with a dash
(-). I think this should be the desired behaviour anyway...


Index: host.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/bind/host/host.c,v
retrieving revision 1.4
diff -u -r1.4 host.c
--- host.c	1999/06/30 12:27:34	1.4
+++ host.c	1999/11/12 19:20:49
@@ -162,6 +162,12 @@
 static int		ListHosts(char *namePtr, int queryType);
 static const char *	DecodeError(int result);
 
+static void
+usage(void) {
+	fprintf(stderr, "Usage: host [-w] [-v] [-r] [-d] [-t querytype] [-c class] [-a] host [server]\n  -w to wait forever until reply\n  -v for verbose output\n  -r to disable recursive processing\n  -d to turn on debugging output\n  -t querytype to look for a specific type of information\n  -c class to look for non-Internet data\n  -a is equivalent to '-v -t *'\n");
+	exit(1);
+}
+
 /* Public. */
 
 int
@@ -175,63 +181,44 @@
 	res_init();
 	_res.retrans = 5;
 
-	if (c < 2) {
-		fprintf(stderr, "Usage: host [-w] [-v] [-r] [-d] [-t querytype] [-c class] [-a] host [server]\n  -w to wait forever until reply\n  -v for verbose output\n  -r to disable recursive processing\n  -d to turn on debugging output\n  -t querytype to look for a specific type of information\n  -c class to look for non-Internet data\n  -a is equivalent to '-v -t *'\n");
-		exit(1);
-	}
 	while (c > 2 && v[1][0] == '-') {
 		if (strcmp (v[1], "-w") == 0) {
 			_res.retry = 1;
 			_res.retrans = 15;
 			waitmode = 1;
-			v++;
-			c--;
 		}
-		else if (strcmp (v[1], "-r") == 0) {
+		else if (strcmp (v[1], "-r") == 0)
 			_res.options &= ~RES_RECURSE;
-			v++;
-			c--;
-		}
-		else if (strcmp (v[1], "-d") == 0) {
+		else if (strcmp (v[1], "-d") == 0)
 			_res.options |= RES_DEBUG;
-			v++;
-			c--;
-		}
-		else if (strcmp (v[1], "-v") == 0) {
+		else if (strcmp (v[1], "-v") == 0)
 			verbose = 1;
-			v++;
-			c--;
-		}
-		else if (strcmp (v[1], "-l") == 0) {
+		else if (strcmp (v[1], "-l") == 0)
 			list = 1;
-			v++;
-			c--;
-		}
 		else if (strncmp (v[1], "-t", 2) == 0) {
 			v++;
 			c--;
 			gettype = parsetype(v[1]);
-			v++;
-			c--;
 		}
 		else if (strncmp (v[1], "-c", 2) == 0) {
 			v++;
 			c--;
 			getclass = parseclass(v[1]);
-			v++;
-			c--;
 		}
 		else if (strcmp (v[1], "-a") == 0) {
 			verbose = 1;
 			gettype = ns_t_any;
-			v++;
-			c--;
-		}		
+		}
+		else
+			usage();
+		v++;
+		c--;
         }
+
 	if (c > 2) {
 		s = v[2];
 		server_specified++;
-		
+
 		if (!inet_aton(s, &addr)) {
 			hp = gethostbyname(s);
 			if (hp == NULL) {
@@ -253,6 +240,10 @@
 		_res.nscount = 1;
 		_res.retry = 2;
 	}
+
+	if (c < 2 || v[1][0] == '-')
+		usage();
+
 	if (strcmp(v[1], ".") == 0 || !inet_aton(v[1], &addr))
 		addr.s_addr = INADDR_NONE;
 	hp = NULL;
>Audit-Trail:
>Unformatted: