ndb/dns: fix leak in myaddr(), normalize ip strings
remove myaddr() function and replace with myip() function that receives binary ip address. and don't use string comparsion for ip addresses... parse and then ipcmp(). for sanity reasons, normalize ip address strings and reject unparsable ones. done by calling ipalookup() with a binary ip address.
This commit is contained in:
parent
b3b938d5ec
commit
549a6745e3
|
@ -316,8 +316,7 @@ dblookup1(char *name, int type, int auth, int ttl)
|
||||||
nstrcpy(dname, nt->val, sizeof dname);
|
nstrcpy(dname, nt->val, sizeof dname);
|
||||||
found = 1;
|
found = 1;
|
||||||
}
|
}
|
||||||
if(strcmp(attr, nt->attr) == 0){
|
if(strcmp(attr, nt->attr) == 0 && (rp = (*f)(t, nt)) != nil){
|
||||||
rp = (*f)(t, nt);
|
|
||||||
rp->auth = auth;
|
rp->auth = auth;
|
||||||
rp->db = 1;
|
rp->db = 1;
|
||||||
if(ttl)
|
if(ttl)
|
||||||
|
@ -336,12 +335,11 @@ dblookup1(char *name, int type, int auth, int ttl)
|
||||||
|
|
||||||
/* search whole entry */
|
/* search whole entry */
|
||||||
for(nt = t; nt; nt = nt->entry)
|
for(nt = t; nt; nt = nt->entry)
|
||||||
if(nt->ptr == 0 && strcmp(attr, nt->attr) == 0){
|
if(nt->ptr == 0 && strcmp(attr, nt->attr) == 0 && (rp = (*f)(t, nt)) != nil){
|
||||||
rp = (*f)(t, nt);
|
rp->auth = auth;
|
||||||
rp->db = 1;
|
rp->db = 1;
|
||||||
if(ttl)
|
if(ttl)
|
||||||
rp->ttl = ttl;
|
rp->ttl = ttl;
|
||||||
rp->auth = auth;
|
|
||||||
if(dp == nil)
|
if(dp == nil)
|
||||||
dp = idnlookup(dname, Cin, 1);
|
dp = idnlookup(dname, Cin, 1);
|
||||||
rp->owner = dp;
|
rp->owner = dp;
|
||||||
|
@ -358,26 +356,22 @@ dblookup1(char *name, int type, int auth, int ttl)
|
||||||
* make various types of resource records from a database entry
|
* make various types of resource records from a database entry
|
||||||
*/
|
*/
|
||||||
static RR*
|
static RR*
|
||||||
addrrr(Ndbtuple *entry, Ndbtuple *pair)
|
addrrr(Ndbtuple*, Ndbtuple *pair)
|
||||||
{
|
{
|
||||||
RR *rp;
|
RR *rp;
|
||||||
uchar addr[IPaddrlen];
|
uchar ip[IPaddrlen];
|
||||||
|
|
||||||
USED(entry);
|
if(parseip(ip, pair->val) == -1)
|
||||||
parseip(addr, pair->val);
|
return nil;
|
||||||
if(isv4(addr))
|
rp = rralloc(isv4(ip) ? Ta : Taaaa);
|
||||||
rp = rralloc(Ta);
|
rp->ip = ipalookup(ip, Cin, 1);
|
||||||
else
|
|
||||||
rp = rralloc(Taaaa);
|
|
||||||
rp->ip = dnlookup(pair->val, Cin, 1);
|
|
||||||
return rp;
|
return rp;
|
||||||
}
|
}
|
||||||
static RR*
|
static RR*
|
||||||
nullrr(Ndbtuple *entry, Ndbtuple *pair)
|
nullrr(Ndbtuple*, Ndbtuple *pair)
|
||||||
{
|
{
|
||||||
RR *rp;
|
RR *rp;
|
||||||
|
|
||||||
USED(entry);
|
|
||||||
rp = rralloc(Tnull);
|
rp = rralloc(Tnull);
|
||||||
rp->null->data = (uchar*)estrdup(pair->val);
|
rp->null->data = (uchar*)estrdup(pair->val);
|
||||||
rp->null->dlen = strlen((char*)rp->null->data);
|
rp->null->dlen = strlen((char*)rp->null->data);
|
||||||
|
@ -389,13 +383,12 @@ nullrr(Ndbtuple *entry, Ndbtuple *pair)
|
||||||
* <= 255 byte ones.
|
* <= 255 byte ones.
|
||||||
*/
|
*/
|
||||||
static RR*
|
static RR*
|
||||||
txtrr(Ndbtuple *entry, Ndbtuple *pair)
|
txtrr(Ndbtuple*, Ndbtuple *pair)
|
||||||
{
|
{
|
||||||
RR *rp;
|
RR *rp;
|
||||||
Txt *t, **l;
|
Txt *t, **l;
|
||||||
int i, len, sofar;
|
int i, len, sofar;
|
||||||
|
|
||||||
USED(entry);
|
|
||||||
rp = rralloc(Ttxt);
|
rp = rralloc(Ttxt);
|
||||||
l = &rp->txt;
|
l = &rp->txt;
|
||||||
rp->txt = nil;
|
rp->txt = nil;
|
||||||
|
@ -420,11 +413,10 @@ txtrr(Ndbtuple *entry, Ndbtuple *pair)
|
||||||
return rp;
|
return rp;
|
||||||
}
|
}
|
||||||
static RR*
|
static RR*
|
||||||
cnamerr(Ndbtuple *entry, Ndbtuple *pair)
|
cnamerr(Ndbtuple*, Ndbtuple *pair)
|
||||||
{
|
{
|
||||||
RR *rp;
|
RR *rp;
|
||||||
|
|
||||||
USED(entry);
|
|
||||||
rp = rralloc(Tcname);
|
rp = rralloc(Tcname);
|
||||||
rp->host = idnlookup(pair->val, Cin, 1);
|
rp->host = idnlookup(pair->val, Cin, 1);
|
||||||
return rp;
|
return rp;
|
||||||
|
@ -453,11 +445,10 @@ nsrr(Ndbtuple *entry, Ndbtuple *pair)
|
||||||
return rp;
|
return rp;
|
||||||
}
|
}
|
||||||
static RR*
|
static RR*
|
||||||
ptrrr(Ndbtuple *entry, Ndbtuple *pair)
|
ptrrr(Ndbtuple*, Ndbtuple *pair)
|
||||||
{
|
{
|
||||||
RR *rp;
|
RR *rp;
|
||||||
|
|
||||||
USED(entry);
|
|
||||||
rp = rralloc(Tns);
|
rp = rralloc(Tns);
|
||||||
rp->ptr = dnlookup(pair->val, Cin, 1);
|
rp->ptr = dnlookup(pair->val, Cin, 1);
|
||||||
return rp;
|
return rp;
|
||||||
|
@ -815,33 +806,29 @@ baddelegation(RR *rp, RR *nsrp, uchar *addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
myaddr(char *addr)
|
myip(uchar *ip)
|
||||||
{
|
{
|
||||||
char *line, *sp;
|
char *line, *sp;
|
||||||
char buf[64];
|
char buf[Maxpath];
|
||||||
|
uchar ipa[IPaddrlen];
|
||||||
Biobuf *bp;
|
Biobuf *bp;
|
||||||
|
|
||||||
if(ipcmp(ipaddr, IPnoaddr) == 0)
|
if(ipcmp(ipaddr, IPnoaddr) == 0)
|
||||||
if(myipaddr(ipaddr, mntpt) < 0)
|
if(myipaddr(ipaddr, mntpt) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
snprint(buf, sizeof buf, "%I", ipaddr);
|
if(ipcmp(ipaddr, ip) == 0)
|
||||||
if (strcmp(addr, buf) == 0) {
|
|
||||||
dnslog("rejecting my ip %s as local dns server", addr);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
snprint(buf, sizeof buf, "%s/ipselftab", mntpt);
|
snprint(buf, sizeof buf, "%s/ipselftab", mntpt);
|
||||||
bp = Bopen(buf, OREAD);
|
bp = Bopen(buf, OREAD);
|
||||||
if (bp != nil) {
|
if(bp != nil) {
|
||||||
while ((line = Brdline(bp, '\n')) != nil) {
|
while((line = Brdline(bp, '\n')) != nil) {
|
||||||
line[Blinelen(bp) - 1] = '\0';
|
line[Blinelen(bp) - 1] = '\0';
|
||||||
sp = strchr(line, ' ');
|
if((sp = strchr(line, ' ')) != nil) {
|
||||||
if (sp) {
|
|
||||||
*sp = '\0';
|
*sp = '\0';
|
||||||
if (strcmp(addr, line) == 0) {
|
if(parseip(ipa, line) != -1 && ipcmp(ipa, ip) == 0) {
|
||||||
dnslog("rejecting my ip %s as local dns server",
|
Bterm(bp);
|
||||||
addr);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -851,39 +838,52 @@ myaddr(char *addr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *locdns[20];
|
|
||||||
static QLock locdnslck;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
addlocaldnsserver(DN *dp, int class, char *ipaddr, int i)
|
addlocaldnsserver(DN *dp, int class, char *ipaddr, int i)
|
||||||
{
|
{
|
||||||
int n;
|
|
||||||
DN *nsdp;
|
|
||||||
RR *rp;
|
|
||||||
char buf[32];
|
|
||||||
uchar ip[IPaddrlen];
|
uchar ip[IPaddrlen];
|
||||||
|
DN *nsdp, *ipdp;
|
||||||
|
RR *rp, *tp;
|
||||||
|
int type, n;
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
/* reject our own ip addresses so we don't query ourselves via udp */
|
if(parseip(ip, ipaddr) == -1 || ipcmp(ip, IPnoaddr) == 0){
|
||||||
if (myaddr(ipaddr))
|
dnslog("rejecting bad ip %s as local dns server", ipaddr);
|
||||||
return;
|
|
||||||
|
|
||||||
qlock(&locdnslck);
|
|
||||||
for (n = 0; n < i && n < nelem(locdns) && locdns[n]; n++)
|
|
||||||
if (strcmp(locdns[n], ipaddr) == 0) {
|
|
||||||
dnslog("rejecting duplicate local dns server ip %s",
|
|
||||||
ipaddr);
|
|
||||||
qunlock(&locdnslck);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (n < nelem(locdns))
|
|
||||||
if (locdns[n] == nil || ++n < nelem(locdns))
|
/* reject our own ip addresses so we don't query ourselves via udp */
|
||||||
locdns[n] = strdup(ipaddr); /* remember 1st few local ns */
|
if(myip(ip)){
|
||||||
qunlock(&locdnslck);
|
dnslog("rejecting my ip %I as local dns server", ip);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A or AAAA record */
|
||||||
|
type = isv4(ip) ? Ta : Taaaa;
|
||||||
|
ipdp = ipalookup(ip, class, 1);
|
||||||
|
|
||||||
|
/* check duplicate ip */
|
||||||
|
for(n = 0; n < i; n++){
|
||||||
|
snprint(buf, sizeof buf, "local#dns#server%d", n);
|
||||||
|
nsdp = dnlookup(buf, class, 0);
|
||||||
|
if(nsdp == nil)
|
||||||
|
continue;
|
||||||
|
rp = rrlookup(nsdp, type, NOneg);
|
||||||
|
for(tp = rp; tp != nil; tp = tp->next){
|
||||||
|
if(tp->ip == ipdp){
|
||||||
|
dnslog("rejecting duplicate local dns server ip %I", ip);
|
||||||
|
rrfreelist(rp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rrfreelist(rp);
|
||||||
|
}
|
||||||
|
|
||||||
|
snprint(buf, sizeof buf, "local#dns#server%d", i);
|
||||||
|
nsdp = dnlookup(buf, class, 1);
|
||||||
|
|
||||||
/* ns record for name server, make up an impossible name */
|
/* ns record for name server, make up an impossible name */
|
||||||
rp = rralloc(Tns);
|
rp = rralloc(Tns);
|
||||||
snprint(buf, sizeof buf, "local#dns#server%d", i);
|
|
||||||
nsdp = dnlookup(buf, class, 1);
|
|
||||||
rp->host = nsdp;
|
rp->host = nsdp;
|
||||||
rp->owner = dp; /* e.g., local#dns#servers */
|
rp->owner = dp; /* e.g., local#dns#servers */
|
||||||
rp->local = 1;
|
rp->local = 1;
|
||||||
|
@ -892,12 +892,8 @@ addlocaldnsserver(DN *dp, int class, char *ipaddr, int i)
|
||||||
rrattach(rp, Authoritative); /* will not attach rrs in my area */
|
rrattach(rp, Authoritative); /* will not attach rrs in my area */
|
||||||
dnagenever(dp);
|
dnagenever(dp);
|
||||||
|
|
||||||
/* A or AAAA record */
|
rp = rralloc(type);
|
||||||
if (parseip(ip, ipaddr) >= 0 && isv4(ip))
|
rp->ip = ipdp;
|
||||||
rp = rralloc(Ta);
|
|
||||||
else
|
|
||||||
rp = rralloc(Taaaa);
|
|
||||||
rp->ip = dnlookup(ipaddr, class, 1);
|
|
||||||
rp->owner = nsdp;
|
rp->owner = nsdp;
|
||||||
rp->local = 1;
|
rp->local = 1;
|
||||||
rp->db = 1;
|
rp->db = 1;
|
||||||
|
@ -905,7 +901,7 @@ addlocaldnsserver(DN *dp, int class, char *ipaddr, int i)
|
||||||
rrattach(rp, Authoritative); /* will not attach rrs in my area */
|
rrattach(rp, Authoritative); /* will not attach rrs in my area */
|
||||||
dnagenever(nsdp);
|
dnagenever(nsdp);
|
||||||
|
|
||||||
dnslog("added local dns server %s at %s", buf, ipaddr);
|
dnslog("added local dns server %s at %I", buf, ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -917,7 +913,7 @@ dnsservers(int class)
|
||||||
{
|
{
|
||||||
int i, n;
|
int i, n;
|
||||||
char *p;
|
char *p;
|
||||||
char *args[5];
|
char *args[16];
|
||||||
Ndbtuple *t, *nt;
|
Ndbtuple *t, *nt;
|
||||||
RR *nsrp;
|
RR *nsrp;
|
||||||
DN *dp;
|
DN *dp;
|
||||||
|
@ -1208,8 +1204,7 @@ insidens(uchar *ip)
|
||||||
|
|
||||||
for (t = innmsrvs; t != nil; t = t->entry)
|
for (t = innmsrvs; t != nil; t = t->entry)
|
||||||
if (strcmp(t->attr, "ip") == 0) {
|
if (strcmp(t->attr, "ip") == 0) {
|
||||||
parseip(ipa, t->val);
|
if (parseip(ipa, t->val) != -1 && ipcmp(ipa, ip) == 0)
|
||||||
if (memcmp(ipa, ip, sizeof ipa) == 0)
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1224,7 +1219,8 @@ outsidensip(int n, uchar *ip)
|
||||||
i = 0;
|
i = 0;
|
||||||
for (t = outnmsrvs; t != nil; t = t->entry)
|
for (t = outnmsrvs; t != nil; t = t->entry)
|
||||||
if (strcmp(t->attr, "ip") == 0 && i++ == n) {
|
if (strcmp(t->attr, "ip") == 0 && i++ == n) {
|
||||||
parseip(ip, t->val);
|
if (parseip(ip, t->val) == -1)
|
||||||
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -233,6 +233,15 @@ idnlookup(char *name, int class, int enter)
|
||||||
return dnlookup(name, class, enter);
|
return dnlookup(name, class, enter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DN*
|
||||||
|
ipalookup(uchar *ip, int class, int enter)
|
||||||
|
{
|
||||||
|
char addr[64];
|
||||||
|
|
||||||
|
snprint(addr, sizeof(addr), "%I", ip);
|
||||||
|
return dnlookup(addr, class, enter);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rrsame(RR *rr1, RR *rr2)
|
rrsame(RR *rr1, RR *rr2)
|
||||||
{
|
{
|
||||||
|
|
|
@ -922,13 +922,12 @@ static int
|
||||||
mydnsquery(Query *qp, int medium, uchar *udppkt, int len)
|
mydnsquery(Query *qp, int medium, uchar *udppkt, int len)
|
||||||
{
|
{
|
||||||
int rv, nfd;
|
int rv, nfd;
|
||||||
char conndir[40], addr[128], domain[64];
|
char conndir[40], addr[128];
|
||||||
uchar belen[2];
|
uchar belen[2];
|
||||||
NetConnInfo *nci;
|
NetConnInfo *nci;
|
||||||
|
|
||||||
rv = -1;
|
rv = -1;
|
||||||
snprint(domain, sizeof(domain), "%I", udppkt);
|
if (myip(udppkt))
|
||||||
if (myaddr(domain))
|
|
||||||
return rv;
|
return rv;
|
||||||
switch (medium) {
|
switch (medium) {
|
||||||
case Udp:
|
case Udp:
|
||||||
|
@ -958,9 +957,8 @@ mydnsquery(Query *qp, int medium, uchar *udppkt, int len)
|
||||||
case Tcp:
|
case Tcp:
|
||||||
/* send via TCP & keep fd around for reply */
|
/* send via TCP & keep fd around for reply */
|
||||||
memmove(qp->tcpip, udppkt, sizeof qp->tcpip);
|
memmove(qp->tcpip, udppkt, sizeof qp->tcpip);
|
||||||
snprint(addr, sizeof addr, "%s/tcp!%s!dns",
|
snprint(addr, sizeof addr, "%s/tcp!%I!dns",
|
||||||
(mntpt && *mntpt) ? mntpt : "/net",
|
(mntpt && *mntpt) ? mntpt : "/net", udppkt);
|
||||||
domain);
|
|
||||||
alarm(10*1000);
|
alarm(10*1000);
|
||||||
qp->tcpfd = dial(addr, nil, conndir, &qp->tcpctlfd);
|
qp->tcpfd = dial(addr, nil, conndir, &qp->tcpctlfd);
|
||||||
alarm(0);
|
alarm(0);
|
||||||
|
@ -1049,7 +1047,7 @@ xmitquery(Query *qp, int medium, int depth, uchar *obuf, int inns, int len)
|
||||||
if((1<<p->nx) > qp->ndest)
|
if((1<<p->nx) > qp->ndest)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(memcmp(p->a, IPnoaddr, sizeof IPnoaddr) == 0)
|
if(ipcmp(p->a, IPnoaddr) == 0)
|
||||||
continue; /* mistake */
|
continue; /* mistake */
|
||||||
|
|
||||||
procsetname("udp %sside query to %I/%s %s %s",
|
procsetname("udp %sside query to %I/%s %s %s",
|
||||||
|
@ -1387,7 +1385,7 @@ queryns(Query *qp, int depth, uchar *ibuf, uchar *obuf, ulong waitms, int inns)
|
||||||
if(debug)
|
if(debug)
|
||||||
dnslog("queryns got reply from %I", srcip);
|
dnslog("queryns got reply from %I", srcip);
|
||||||
for(p = qp->dest; p < qp->curdest; p++)
|
for(p = qp->dest; p < qp->curdest; p++)
|
||||||
if(memcmp(p->a, srcip, sizeof p->a) == 0)
|
if(ipcmp(p->a, srcip) == 0)
|
||||||
break;
|
break;
|
||||||
if(p >= qp->curdest){
|
if(p >= qp->curdest){
|
||||||
dnslog("response from %I but no destination", srcip);
|
dnslog("response from %I but no destination", srcip);
|
||||||
|
|
|
@ -449,13 +449,12 @@ void dnagedb(void);
|
||||||
void dnagenever(DN *);
|
void dnagenever(DN *);
|
||||||
void dnauthdb(void);
|
void dnauthdb(void);
|
||||||
void dndump(char*);
|
void dndump(char*);
|
||||||
void dnget(void);
|
|
||||||
void dninit(void);
|
void dninit(void);
|
||||||
DN* dnlookup(char*, int, int);
|
DN* dnlookup(char*, int, int);
|
||||||
DN* idnlookup(char*, int, int);
|
DN* idnlookup(char*, int, int);
|
||||||
|
DN* ipalookup(uchar*, int, int);
|
||||||
void dnptr(uchar*, uchar*, char*, int, int, int);
|
void dnptr(uchar*, uchar*, char*, int, int, int);
|
||||||
void dnpurge(void);
|
void dnpurge(void);
|
||||||
void dnput(void);
|
|
||||||
void dnslog(char*, ...);
|
void dnslog(char*, ...);
|
||||||
void dnstats(char *file);
|
void dnstats(char *file);
|
||||||
void* emalloc(int);
|
void* emalloc(int);
|
||||||
|
@ -501,7 +500,7 @@ RR* dnsservers(int);
|
||||||
RR* domainlist(int);
|
RR* domainlist(int);
|
||||||
int insideaddr(char *dom);
|
int insideaddr(char *dom);
|
||||||
int insidens(uchar *ip);
|
int insidens(uchar *ip);
|
||||||
int myaddr(char *addr);
|
int myip(uchar *ip);
|
||||||
int opendatabase(void);
|
int opendatabase(void);
|
||||||
int outsidensip(int, uchar *ip);
|
int outsidensip(int, uchar *ip);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue