ref: 182077ac24010f8065755ea903bf57c829b0220a
parent: 0cf8a0c4a8fb8a13ed46e1007dc65124248e5cab
author: cinap_lenrek <cinap_lenrek@felloff.net>
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;
}
}