pcre's behavior is changed so that pcre2_match always allocates heap for match_data, rather than stack, regardless of size. The heap isn't freed until explicitly calling pcre2_match_data_free. This new behavior may result in heap overhead, which may increase the peak memory usage about a few megabytes. It's because regex_match is first called for regex_data objects, and then regex_data objects are freed at once. To workaround it, free and reallocate match_data whenever we call regex_match. It's fine because libselinux currently doesn't use match_data, but use only the return value. Signed-off-by: Inseob Kim <inseob@xxxxxxxxxx> --- libselinux/src/regex.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libselinux/src/regex.c b/libselinux/src/regex.c index 149a7973..2df282f1 100644 --- a/libselinux/src/regex.c +++ b/libselinux/src/regex.c @@ -213,10 +213,20 @@ void regex_data_free(struct regex_data *regex) int regex_match(struct regex_data *regex, char const *subject, int partial) { int rc; + pcre2_match_data *new_match_data; __pthread_mutex_lock(®ex->match_mutex); + new_match_data = pcre2_match_data_create_from_pattern( + regex->regex, NULL); rc = pcre2_match( regex->regex, (PCRE2_SPTR)subject, PCRE2_ZERO_TERMINATED, 0, partial ? PCRE2_PARTIAL_SOFT : 0, regex->match_data, NULL); + // pcre2_match allocates heap and it won't be freed until + // pcre2_match_data_free, resulting in heap overhead. + // Reallocate match_data to prevent such overhead, whenever possible. + if (new_match_data) { + pcre2_match_data_free(regex->match_data); + regex->match_data = new_match_data; + } __pthread_mutex_unlock(®ex->match_mutex); if (rc > 0) return REGEX_MATCH; -- 2.39.0.314.g84b9a713c41-goog