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;
|
||||
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 */
|
||||
|
|
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)
|
||||
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.
|
||||
|
|
Loading…
Reference in New Issue