A previous patch reimplemented a single threaded fallback while keeping the memory usage low as was done originally by the workaround, but the resulting code is too slow. To improve performance, while keeping memory in check, use instead a static match_data that gets reused for all queries and let its contents (including the heapframes) leak. Signed-off-by: Carlo Marcelo Arenas Belón <carenas@xxxxxxxxx> --- libselinux/src/regex.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/libselinux/src/regex.c b/libselinux/src/regex.c index 54f24026..a6b44023 100644 --- a/libselinux/src/regex.c +++ b/libselinux/src/regex.c @@ -220,7 +220,8 @@ void regex_data_free(struct regex_data *regex) int regex_match(struct regex_data *regex, char const *subject, int partial) { int rc; - bool slow; + bool single_threaded; + static pcre2_match_data *static_match_data; pcre2_match_data *match_data = NULL; if (match_data_key_initialized > 0) { @@ -238,10 +239,13 @@ int regex_match(struct regex_data *regex, char const *subject, int partial) match_data = __selinux_getspecific(match_data_key); } - slow = (match_data_key_initialized <= 0 || match_data == NULL); - if (slow) { - match_data = pcre2_match_data_create_from_pattern(regex->regex, - NULL); + single_threaded = (match_data_key_initialized <= 0 || !match_data); + if (single_threaded) { + if (!static_match_data && !match_data_initialized) + static_match_data = pcre2_match_data_create(1, NULL); + + match_data_initialized = 1; + match_data = static_match_data; if (!match_data) return REGEX_ERROR; } @@ -250,9 +254,6 @@ int regex_match(struct regex_data *regex, char const *subject, int partial) regex->regex, (PCRE2_SPTR)subject, PCRE2_ZERO_TERMINATED, 0, partial ? PCRE2_PARTIAL_SOFT : 0, match_data, NULL); - if (slow) - pcre2_match_data_free(match_data); - if (rc >= 0) return REGEX_MATCH; switch (rc) { -- 2.39.0