From: Victor Julien Date: Tue, 14 Apr 2020 06:01:49 +0000 (+0200) Subject: detect/address: limit recursion during parsing X-Git-Tag: suricata-5.0.3~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=df5d715c335dc1e0b62c6cf55513fdac03a617a7;p=thirdparty%2Fsuricata.git detect/address: limit recursion during parsing Allow a max depth of 64. Bug: #3600 --- diff --git a/src/detect-engine-address.c b/src/detect-engine-address.c index 4d66d6a537..b0315451c1 100644 --- a/src/detect-engine-address.c +++ b/src/detect-engine-address.c @@ -735,7 +735,8 @@ static int DetectAddressSetup(DetectAddressHead *gh, const char *s) */ static int DetectAddressParse2(const DetectEngineCtx *de_ctx, DetectAddressHead *gh, DetectAddressHead *ghn, - const char *s, int negate, ResolvedVariablesList *var_list) + const char *s, int negate, ResolvedVariablesList *var_list, + int recur) { size_t x = 0; size_t u = 0; @@ -746,6 +747,12 @@ static int DetectAddressParse2(const DetectEngineCtx *de_ctx, const char *rule_var_address = NULL; char *temp_rule_var_address = NULL; + if (++recur > 64) { + SCLogError(SC_ERR_ADDRESS_ENGINE_GENERIC, "address block recursion " + "limit reached (max 64)"); + goto error; + } + SCLogDebug("s %s negate %s", s, negate ? "true" : "false"); for (u = 0, x = 0; u < size && x < sizeof(address); u++) { @@ -776,7 +783,7 @@ static int DetectAddressParse2(const DetectEngineCtx *de_ctx, /* normal block */ SCLogDebug("normal block"); - if (DetectAddressParse2(de_ctx, gh, ghn, address, (negate + n_set) % 2, var_list) < 0) + if (DetectAddressParse2(de_ctx, gh, ghn, address, (negate + n_set) % 2, var_list, recur) < 0) goto error; } else { /* negated block @@ -789,7 +796,7 @@ static int DetectAddressParse2(const DetectEngineCtx *de_ctx, DetectAddressHead tmp_gh = { NULL, NULL }; DetectAddressHead tmp_ghn = { NULL, NULL }; - if (DetectAddressParse2(de_ctx, &tmp_gh, &tmp_ghn, address, 0, var_list) < 0) { + if (DetectAddressParse2(de_ctx, &tmp_gh, &tmp_ghn, address, 0, var_list, recur) < 0) { DetectAddressHeadCleanup(&tmp_gh); DetectAddressHeadCleanup(&tmp_ghn); goto error; @@ -889,7 +896,7 @@ static int DetectAddressParse2(const DetectEngineCtx *de_ctx, if (DetectAddressParse2(de_ctx, gh, ghn, temp_rule_var_address, - (negate + n_set) % 2, var_list) < 0) + (negate + n_set) % 2, var_list, recur) < 0) { if (temp_rule_var_address != rule_var_address) SCFree(temp_rule_var_address); @@ -957,7 +964,7 @@ static int DetectAddressParse2(const DetectEngineCtx *de_ctx, } if (DetectAddressParse2(de_ctx, gh, ghn, temp_rule_var_address, - (negate + n_set) % 2, var_list) < 0) { + (negate + n_set) % 2, var_list, recur) < 0) { SCLogDebug("DetectAddressParse2 hates us"); if (temp_rule_var_address != rule_var_address) SCFree(temp_rule_var_address); @@ -1251,7 +1258,7 @@ int DetectAddressTestConfVars(void) goto error; } - int r = DetectAddressParse2(NULL, gh, ghn, seq_node->val, /* start with negate no */0, &var_list); + int r = DetectAddressParse2(NULL, gh, ghn, seq_node->val, /* start with negate no */0, &var_list, 0); CleanVariableResolveList(&var_list); @@ -1409,7 +1416,7 @@ int DetectAddressParse(const DetectEngineCtx *de_ctx, return -1; } - int r = DetectAddressParse2(de_ctx, gh, ghn, str, /* start with negate no */0, NULL); + int r = DetectAddressParse2(de_ctx, gh, ghn, str, /* start with negate no */0, NULL, 0); if (r < 0) { SCLogDebug("DetectAddressParse2 returned %d", r); DetectAddressHeadFree(ghn); @@ -2291,6 +2298,32 @@ static int AddressTestParse25(void) PASS; } +/** \test recursion limit */ +static int AddressTestParse26(void) +{ + DetectAddressHead *gh = DetectAddressHeadInit(); + FAIL_IF_NULL(gh); + /* exactly 64: should pass */ + int r = DetectAddressParse(NULL, gh, + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "1.2.3.4" + "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]" + ); + FAIL_IF_NOT(r == 0); + DetectAddressHeadFree(gh); + gh = DetectAddressHeadInit(); + FAIL_IF_NULL(gh); + /* exactly 65: should fail */ + r = DetectAddressParse(NULL, gh, + "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" + "1.2.3.4" + "]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]" + ); + FAIL_IF(r == 0); + DetectAddressHeadFree(gh); + PASS; +} + static int AddressTestParse27(void) { DetectAddress *dd = DetectAddressParseSingle("!192.168.0.1"); @@ -4827,6 +4860,7 @@ void DetectAddressTests(void) UtRegisterTest("AddressTestParse23", AddressTestParse23); UtRegisterTest("AddressTestParse24", AddressTestParse24); UtRegisterTest("AddressTestParse25", AddressTestParse25); + UtRegisterTest("AddressTestParse26", AddressTestParse26); UtRegisterTest("AddressTestParse27", AddressTestParse27); UtRegisterTest("AddressTestParse28", AddressTestParse28); UtRegisterTest("AddressTestParse29", AddressTestParse29);