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:
parent
27614b6b35
commit
179ca703b2
|
@ -40,9 +40,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||||
{
|
{
|
||||||
static int first_run = 1;
|
static int first_run = 1;
|
||||||
psl_ctx_t *psl;
|
psl_ctx_t *psl;
|
||||||
char *domain = (char *) malloc(size + 1), *res;
|
char *domain, *res;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (size > 64 * 1024 - 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
domain = (char *) malloc(size + 1);
|
||||||
assert(domain != NULL);
|
assert(domain != NULL);
|
||||||
|
|
||||||
/* 0 terminate */
|
/* 0 terminate */
|
||||||
|
|
26
src/psl.c
26
src/psl.c
|
@ -1048,6 +1048,19 @@ const char *psl_unregistrable_domain(const psl_ctx_t *psl, const char *domain)
|
||||||
if (!psl || !domain)
|
if (!psl || !domain)
|
||||||
return NULL;
|
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':
|
* 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.
|
* '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 == '.')
|
if (!psl || !domain || *domain == '.')
|
||||||
return NULL;
|
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':
|
* 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.
|
* 'forgot.his.name' and 'name' are in the PSL while 'his.name' is not.
|
||||||
|
|
Loading…
Reference in New Issue