mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-14 10:09:48 +00:00
Introduce a new helper function check_search() derived for res_hnok to
check the domain-name parameter according to the rules for "search" strings as documented in resolv.conf(5). Specifically, the string must be no more than 256 bytes long and contain no more than six valid domain names separated by white space. The previous unchecked values could result in a mangled resolv.conf file which could effectively deny access to local sites. This is not a security issue as rogue dhcp servers could already do this without sending invalid strings. Reviewed by: cperciva MFC After: 3 days
This commit is contained in:
parent
c313f09bfb
commit
f954ec0bcf
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=149639
@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$");
|
||||
#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) || \
|
||||
((c) >= 0x61 && (c) <= 0x7a))
|
||||
#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
|
||||
#define whitechar(c) ((c) == ' ' || (c) == '\t')
|
||||
|
||||
#define borderchar(c) (alphachar(c) || digitchar(c))
|
||||
#define middlechar(c) (borderchar(c) || hyphenchar(c))
|
||||
@ -116,6 +117,7 @@ void usage(void);
|
||||
int check_option(struct client_lease *l, int option);
|
||||
int ipv4addrs(char * buf);
|
||||
int res_hnok(const char *dn);
|
||||
int check_search(const char *srch);
|
||||
char *option_as_string(unsigned int code, unsigned char *data, int len);
|
||||
int fork_privchld(int, int);
|
||||
|
||||
@ -2250,6 +2252,14 @@ check_option(struct client_lease *l, int option)
|
||||
}
|
||||
return (1);
|
||||
case DHO_DOMAIN_NAME:
|
||||
if (!res_hnok(sbuf)) {
|
||||
if (!check_search(sbuf)) {
|
||||
warning("Bogus domain search list %d: %s (%s)",
|
||||
option, sbuf, opbuf);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
return (1);
|
||||
case DHO_PAD:
|
||||
case DHO_TIME_OFFSET:
|
||||
case DHO_BOOT_SIZE:
|
||||
@ -2325,6 +2335,52 @@ res_hnok(const char *dn)
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
check_search(const char *srch)
|
||||
{
|
||||
int pch = PERIOD, ch = *srch++;
|
||||
int domains = 1;
|
||||
|
||||
/* 256 char limit re resolv.conf(5) */
|
||||
if (strlen(srch) > 256)
|
||||
return (0);
|
||||
|
||||
while (whitechar(ch))
|
||||
ch = *srch++;
|
||||
|
||||
while (ch != '\0') {
|
||||
int nch = *srch++;
|
||||
|
||||
if (periodchar(ch) || whitechar(ch)) {
|
||||
;
|
||||
} else if (periodchar(pch)) {
|
||||
if (!borderchar(ch))
|
||||
return (0);
|
||||
} else if (periodchar(nch) || nch == '\0') {
|
||||
if (!borderchar(ch))
|
||||
return (0);
|
||||
} else {
|
||||
if (!middlechar(ch))
|
||||
return (0);
|
||||
}
|
||||
if (!whitechar(ch)) {
|
||||
pch = ch;
|
||||
} else {
|
||||
while (whitechar(nch)) {
|
||||
nch = *srch++;
|
||||
}
|
||||
if (nch != '\0')
|
||||
domains++;
|
||||
pch = PERIOD;
|
||||
}
|
||||
ch = nch;
|
||||
}
|
||||
/* 6 domain limit re resolv.conf(5) */
|
||||
if (domains > 6)
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Does buf consist only of dotted decimal ipv4 addrs?
|
||||
* return how many if so,
|
||||
* otherwise, return 0
|
||||
|
Loading…
Reference in New Issue
Block a user