Limit CPU wasting on large inputs

Large inputs on psl_registrable_domain() and psl_unregistrable_domain()
suffer from a O(N^2) behavior. This change limits N to avoid excessive
CPU usage.

At the same time we limit the fuzz corpora size to 64k which is far more
then we expect any real life domain to be.

Reported-by: OSS-Fuzz
This commit is contained in:
Tim Rühsen 2018-02-13 15:41:58 +01:00
parent 27614b6b35
commit 179ca703b2
2 changed files with 31 additions and 1 deletions

View File

@ -40,9 +40,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
static int first_run = 1;
psl_ctx_t *psl;
char *domain = (char *) malloc(size + 1), *res;
char *domain, *res;
int rc;
if (size > 64 * 1024 - 1)
return 0;
domain = (char *) malloc(size + 1);
assert(domain != NULL);
/* 0 terminate */

View File

@ -1048,6 +1048,19 @@ const char *psl_unregistrable_domain(const psl_ctx_t *psl, const char *domain)
if (!psl || !domain)
return NULL;
/*
* In the main loop we introduce a O(N^2) behavior to avoid code duplication.
* To avoid nasty CPU hogging, we limit the lookup to max. 8 domain labels to the right.
*/
int nlabels = 0;
for (const char *p = domain + strlen(domain) - 1; p >= domain; p--) {
if (*p == '.' && ++nlabels > 8) {
domain = p + 1;
break;
}
}
/*
* We check from left to right to catch special PSL entries like 'forgot.his.name':
* 'forgot.his.name' and 'name' are in the PSL while 'his.name' is not.
@ -1090,6 +1103,19 @@ const char *psl_registrable_domain(const psl_ctx_t *psl, const char *domain)
if (!psl || !domain || *domain == '.')
return NULL;
/*
* In the main loop we introduce a O(N^2) behavior to avoid code duplication.
* To avoid nasty CPU hogging, we limit the lookup to max. 8 domain labels to the right.
*/
int nlabels = 0;
for (p = domain + strlen(domain) - 1; p >= domain; p--) {
if (*p == '.' && ++nlabels > 8) {
domain = p + 1;
break;
}
}
/*
* We check from left to right to catch special PSL entries like 'forgot.his.name':
* 'forgot.his.name' and 'name' are in the PSL while 'his.name' is not.