shithub: riscv

Download patch

ref: 182077ac24010f8065755ea903bf57c829b0220a
parent: 0cf8a0c4a8fb8a13ed46e1007dc65124248e5cab
author: cinap_lenrek <[email protected]>
date: Sun Jun 3 16:52:10 EDT 2018

ip/dhcpd: parseip() error handling, make sure client ip is ipv4, add explicit length arguments to lookupname() and lookupserver()

--- a/sys/src/cmd/ip/dhcpd/dat.h
+++ b/sys/src/cmd/ip/dhcpd/dat.h
@@ -67,10 +67,10 @@
 /* from ndb.c */
 extern int	lookup(Bootp*, Info*, Info*);
 extern int	lookupip(uchar*, Info*, int);
-extern void	lookupname(char*, Ndbtuple*);
+extern void	lookupname(char*, int, Ndbtuple*);
 extern Iplifc*	findlifc(uchar*);
 extern int	forme(uchar*);
-extern int	lookupserver(char*, uchar**, Ndbtuple *t);
+extern int	lookupserver(char*, uchar**, int, Ndbtuple *t);
 extern Ndbtuple* lookupinfo(uchar *ipaddr, char **attr, int n);
 
 /* from icmp.c */
--- a/sys/src/cmd/ip/dhcpd/dhcpd.c
+++ b/sys/src/cmd/ip/dhcpd/dhcpd.c
@@ -51,7 +51,7 @@
 #define TFTP "/lib/tftpd"
 
 char	*blog = "ipboot";
-char	mysysname[64];
+char	*mysysname;
 Ipifc	*ipifcs;
 int	debug;
 int	nobootp;
@@ -273,8 +273,7 @@
 	} ARGEND;
 
 	while(argc > 1){
-		parseip(ip, argv[0]);
-		if(!validip(ip))
+		if(parseip(ip, argv[0]) == -1 || !validip(ip))
 			usage();
 		n = atoi(argv[1]);
 		if(n <= 0)
@@ -290,7 +289,7 @@
 			optname[i] = smprint("%d", i);
 
 	/* what is my name? */
-	strcpy(mysysname, readsysname());
+	mysysname = readsysname();
 
 	/* put process in background */
 	if(!debug)
@@ -554,7 +553,7 @@
 		 */
 		/* check for hard assignment */
 		if(rp->staticbinding){
-			if(memcmp(rp->ip, rp->ii.ipaddr, IPaddrlen) != 0){
+			if(ipcmp(rp->ip, rp->ii.ipaddr) != 0){
 				warning(0, "!Request(%s via %I): %I not valid for %E",
 					rp->id, rp->gii.ipaddr, rp->ip, rp->bp->chaddr);
 				sendnak(rp, "not valid");
@@ -577,7 +576,7 @@
 				rp->id, rp->gii.ipaddr, rp->ip);
 			return;
 		}
-		if(memcmp(rp->ip, b->ip, IPaddrlen) != 0 || now > b->lease){
+		if(ipcmp(rp->ip, b->ip) != 0 || now > b->lease){
 			warning(0, "!Request(%s via %I): %I not valid",
 				rp->id, rp->gii.ipaddr, rp->ip);
 			sendnak(rp, "not valid");
@@ -1109,7 +1108,7 @@
 			memmove(rp->vendorclass, o, n);
 			rp->vendorclass[n] = 0;
 			if(strncmp((char*)rp->vendorclass, "p9-", 3) == 0)
-				strcpy(rp->cputype, (char*)rp->vendorclass+3);
+				strncpy(rp->cputype, (char*)rp->vendorclass+3, sizeof(rp->cputype));
 			break;
 		case OBend:
 			return;
@@ -1131,15 +1130,15 @@
 miscoptions(Req *rp, uchar *ip)
 {
 	int i, j, na;
-	uchar x[2*IPaddrlen], vopts[Maxoptlen];
+	uchar *addrs[8];
 	uchar *op, *omax;
-	uchar *addrs[2];
+	uchar x[nelem(addrs)*IPaddrlen], vopts[Maxoptlen];
 	char *p;
 	char *attr[100], **a;
 	Ndbtuple *t;
 
-	addrs[0] = x;
-	addrs[1] = x+IPaddrlen;
+	for(i=0; i<nelem(addrs); i++)
+		addrs[i] = &x[i*IPaddrlen];
 
 	/* always supply these */
 	maskopt(rp, OBmask, rp->gii.ipmask);
@@ -1203,17 +1202,17 @@
 
 	/* lookup anything we might be missing */
 	if(*rp->ii.domain == 0)
-		lookupname(rp->ii.domain, t);
+		lookupname(rp->ii.domain, sizeof(rp->ii.domain), t);
 
 	/* add any requested ones that we know about */
 	for(i = 0; i < sizeof(rp->requested); i++)
 		switch(rp->requested[i]){
 		case OBrouter:
-			j = lookupserver("ipgw", addrs, t);
+			j = lookupserver("ipgw", addrs, nelem(addrs), t);
 			addrsopt(rp, OBrouter, addrs, j);
 			break;
 		case OBdnserver:
-			j = lookupserver("dns", addrs, t);
+			j = lookupserver("dns", addrs, nelem(addrs), t);
 			addrsopt(rp, OBdnserver, addrs, j);
 			break;
 		case OBhostname:
@@ -1222,11 +1221,11 @@
 			break;
 		case OBdomainname:
 			p = strchr(rp->ii.domain, '.');
-			if(p)
+			if(p != nil)
 				stringopt(rp, OBdomainname, p+1);
 			break;
 		case OBnetbiosns:
-			j = lookupserver("wins", addrs, t);
+			j = lookupserver("wins", addrs, nelem(addrs), t);
 			addrsopt(rp, OBnetbiosns, addrs, j);
 			break;
 		case OBnetbiostype:
@@ -1234,23 +1233,23 @@
 			byteopt(rp, OBnetbiostype, 0x2);
 			break;
 		case OBsmtpserver:
-			j = lookupserver("smtp", addrs, t);
+			j = lookupserver("smtp", addrs, nelem(addrs), t);
 			addrsopt(rp, OBsmtpserver, addrs, j);
 			break;
 		case OBpop3server:
-			j = lookupserver("pop3", addrs, t);
+			j = lookupserver("pop3", addrs, nelem(addrs), t);
 			addrsopt(rp, OBpop3server, addrs, j);
 			break;
 		case OBwwwserver:
-			j = lookupserver("www", addrs, t);
+			j = lookupserver("www", addrs, nelem(addrs), t);
 			addrsopt(rp, OBwwwserver, addrs, j);
 			break;
 		case OBntpserver:
-			j = lookupserver("ntp", addrs, t);
+			j = lookupserver("ntp", addrs, nelem(addrs), t);
 			addrsopt(rp, OBntpserver, addrs, j);
 			break;
 		case OBtimeserver:
-			j = lookupserver("time", addrs, t);
+			j = lookupserver("time", addrs, nelem(addrs), t);
 			addrsopt(rp, OBtimeserver, addrs, j);
 			break;
 		case OBttl:
@@ -1269,14 +1268,14 @@
 		rp->max = vopts + sizeof(vopts) - 1;
 
 		/* emit old v4 addresses first to make sure that they fit */
-		addrsopt(rp, OP9fsv4, addrs, lookupserver("fs", addrs, t));
-		addrsopt(rp, OP9authv4, addrs, lookupserver("auth", addrs, t));
+		addrsopt(rp, OP9fsv4, addrs, lookupserver("fs", addrs, nelem(addrs), t));
+		addrsopt(rp, OP9authv4, addrs, lookupserver("auth", addrs, nelem(addrs), t));
 
-		p9addrsopt(rp, OP9fs, addrs, lookupserver("fs", addrs, t));
-		p9addrsopt(rp, OP9auth, addrs, lookupserver("auth", addrs, t));
-		p9addrsopt(rp, OP9ipaddr, addrs, lookupserver("ip", addrs, t));
-		p9addrsopt(rp, OP9ipmask, addrs, lookupserver("ipmask", addrs, t));
-		p9addrsopt(rp, OP9ipgw, addrs, lookupserver("ipgw", addrs, t));
+		p9addrsopt(rp, OP9fs, addrs, lookupserver("fs", addrs, nelem(addrs), t));
+		p9addrsopt(rp, OP9auth, addrs, lookupserver("auth", addrs, nelem(addrs), t));
+		p9addrsopt(rp, OP9ipaddr, addrs, lookupserver("ip", addrs, nelem(addrs), t));
+		p9addrsopt(rp, OP9ipmask, addrs, lookupserver("ipmask", addrs, nelem(addrs), t));
+		p9addrsopt(rp, OP9ipgw, addrs, lookupserver("ipgw", addrs, nelem(addrs), t));
 
 		/* point back to packet, encapsulate vopts into packet */
 		j = rp->p - vopts;
--- a/sys/src/cmd/ip/dhcpd/ndb.c
+++ b/sys/src/cmd/ip/dhcpd/ndb.c
@@ -40,12 +40,12 @@
 	Ipifc *ifc;
 	Iplifc *lifc;
 
-	for(ifc = ipifcs; ifc; ifc = ifc->next){
+	for(ifc = ipifcs; ifc != nil; ifc = ifc->next){
 		for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){
 			if(lifc->net[0] == 0)
 				continue;
 			maskip(ip, lifc->mask, x);
-			if(memcmp(x, lifc->net, IPaddrlen) == 0)
+			if(ipcmp(x, lifc->net) == 0)
 				return lifc;
 		}
 	}
@@ -58,9 +58,9 @@
 	Ipifc *ifc;
 	Iplifc *lifc;
 
-	for(ifc = ipifcs; ifc; ifc = ifc->next){
+	for(ifc = ipifcs; ifc != nil; ifc = ifc->next){
 		for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next)
-			if(memcmp(ip, lifc->ip, IPaddrlen) == 0)
+			if(ipcmp(ip, lifc->ip) == 0)
 				return 1;
 	}
 	return 0;
@@ -157,32 +157,32 @@
 		else
 		if(strcmp(nt->attr, "dhcp") == 0){
 			if(iip->dhcpgroup[0] == 0)
-				strcpy(iip->dhcpgroup, nt->val);
+				strncpy(iip->dhcpgroup, nt->val, sizeof(iip->dhcpgroup)-1);
 		}
 		else
 		if(strcmp(nt->attr, "bootf") == 0){
 			if(iip->bootf[0] == 0)
-				strcpy(iip->bootf, nt->val);
+				strncpy(iip->bootf, nt->val, sizeof(iip->bootf)-1);
 		}
 		else
 		if(strcmp(nt->attr, "bootf2") == 0){
 			if(iip->bootf2[0] == 0)
-				strcpy(iip->bootf2, nt->val);
+				strncpy(iip->bootf2, nt->val, sizeof(iip->bootf2)-1);
 		}
 		else
 		if(strcmp(nt->attr, "vendor") == 0){
 			if(iip->vendor[0] == 0)
-				strcpy(iip->vendor, nt->val);
+				strncpy(iip->vendor, nt->val, sizeof(iip->vendor)-1);
 		}
 		else
 		if(strcmp(nt->attr, "dom") == 0){
 			if(iip->domain[0] == 0)
-				strcpy(iip->domain, nt->val);
+				strncpy(iip->domain, nt->val, sizeof(iip->domain)-1);
 		}
 		else
 		if(strcmp(nt->attr, "rootpath") == 0){
 			if(iip->rootpath[0] == 0)
-				strcpy(iip->rootpath, nt->val);
+				strncpy(iip->rootpath, nt->val, sizeof(iip->rootpath)-1);
 		}
 	}
 	ndbfree(t);
@@ -256,11 +256,14 @@
 	 *  same net as riip
 	 */
 	t = ndbsearch(db, &s, hwattr, hwval);
-	while(t){
-		for(nt = t; nt; nt = nt->entry){
+	while(t != nil){
+		for(nt = t; nt != nil; nt = nt->entry){
 			if(strcmp(nt->attr, "ip") != 0)
 				continue;
-			parseip(ciaddr, nt->val);
+			if(parseip(ciaddr, nt->val) == -1)
+				continue;
+			if(!validip(ciaddr))
+				continue;
 			if(lookupip(ciaddr, iip, 0) < 0)
 				continue;
 			if(samenet(riip->ipaddr, iip)){
@@ -280,9 +283,9 @@
 Ndbtuple*
 lookupinfo(uchar *ipaddr, char **attr, int n)
 {
-	char ip[32];
+	char ip[64];
 
-	sprint(ip, "%I", ipaddr);
+	snprint(ip, sizeof ip, "%I", ipaddr);
 	return ndbipinfo(db, "ip", ip, attr, n);
 }
 
@@ -290,16 +293,18 @@
  *  return the ip addresses for a type of server for system ip
  */
 int
-lookupserver(char *attr, uchar **ipaddrs, Ndbtuple *t)
+lookupserver(char *attr, uchar **ipaddrs, int naddrs, Ndbtuple *t)
 {
 	Ndbtuple *nt;
 	int rv = 0;
 
-	for(nt = t; rv < 2 && nt != nil; nt = nt->entry)
-		if(strcmp(nt->attr, attr) == 0){
-			parseip(ipaddrs[rv], nt->val);
-			rv++;
-		}
+	for(nt = t; rv < naddrs && nt != nil; nt = nt->entry){
+		if(strcmp(nt->attr, attr) != 0)
+			continue;
+		if(parseip(ipaddrs[rv], nt->val) == -1)
+			continue;
+		rv++;
+	}
 	return rv;
 }
 
@@ -307,13 +312,14 @@
  *  just lookup the name
  */
 void
-lookupname(char *val, Ndbtuple *t)
+lookupname(char *val, int len, Ndbtuple *t)
 {
 	Ndbtuple *nt;
 
 	for(nt = t; nt != nil; nt = nt->entry)
 		if(strcmp(nt->attr, "dom") == 0){
-			strcpy(val, nt->val);
+			strncpy(val, nt->val, len-1);
+			val[len-1] = 0;
 			break;
 		}
 }