From ce8577d636b2c8f1039133fb4e80da6e2672ca69 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Fri, 4 May 2018 19:20:42 +0100 Subject: [PATCH] [Minor] Try to allow disabling JIT in PCRE --- src/libserver/cfg_file.h | 1 + src/libserver/cfg_rcl.c | 6 ++++ src/libserver/cfg_utils.c | 2 +- src/libutil/regexp.c | 72 ++++++++++++++++++++++----------------- src/libutil/regexp.h | 4 ++- 5 files changed, 51 insertions(+), 34 deletions(-) diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h index 74949e283..a12b16477 100644 --- a/src/libserver/cfg_file.h +++ b/src/libserver/cfg_file.h @@ -310,6 +310,7 @@ struct rspamd_config { gboolean ignore_received; /**< Ignore data from the first received header */ gboolean enable_sessions_cache; /**< Enable session cache for debug */ gboolean enable_experimental; /**< Enable experimental plugins */ + gboolean disable_pcre_jit; /**< Disable pcre JIT */ gsize max_diff; /**< maximum diff size for text parts */ gsize max_cores_size; /**< maximum size occupied by rspamd core files */ diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c index 349bc5cf2..47e730af0 100644 --- a/src/libserver/cfg_rcl.c +++ b/src/libserver/cfg_rcl.c @@ -2026,6 +2026,12 @@ rspamd_rcl_config_init (struct rspamd_config *cfg) G_STRUCT_OFFSET (struct rspamd_config, enable_experimental), 0, "Enable experimental plugins"); + rspamd_rcl_add_default_handler (sub, + "enable_experimental", + rspamd_rcl_parse_struct_boolean, + G_STRUCT_OFFSET (struct rspamd_config, disable_pcre_jit), + 0, + "Disable PCRE JIT"); rspamd_rcl_add_default_handler (sub, "all_filters", rspamd_rcl_parse_struct_boolean, diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c index 3856c294b..76de54e1b 100644 --- a/src/libserver/cfg_utils.c +++ b/src/libserver/cfg_utils.c @@ -685,7 +685,7 @@ rspamd_config_post_load (struct rspamd_config *cfg, cfg->default_max_shots = 1; } - rspamd_regexp_library_init (); + rspamd_regexp_library_init (cfg); rspamd_multipattern_library_init (cfg->hs_cache_dir); #ifdef WITH_HYPERSCAN diff --git a/src/libutil/regexp.c b/src/libutil/regexp.c index 8174a30fc..33bb5711e 100644 --- a/src/libutil/regexp.c +++ b/src/libutil/regexp.c @@ -82,6 +82,7 @@ struct rspamd_regexp_cache { static struct rspamd_regexp_cache *global_re_cache = NULL; static gboolean can_jit = FALSE; +static gboolean check_jit = TRUE; #ifdef WITH_PCRE2 static pcre2_compile_context *pcre2_ctx = NULL; @@ -330,7 +331,7 @@ rspamd_regexp_new (const gchar *pattern, const gchar *flags, gint regexp_flags = 0, rspamd_flags = 0, err_code, ncaptures; gboolean strict_flags = FALSE; - rspamd_regexp_library_init (); + rspamd_regexp_library_init (NULL); if (flags == NULL) { /* We need to parse pattern and detect flags set */ @@ -963,7 +964,7 @@ rspamd_regexp_cache_query (struct rspamd_regexp_cache* cache, regexp_id_t id; if (cache == NULL) { - rspamd_regexp_library_init (); + rspamd_regexp_library_init (NULL); cache = global_re_cache; } @@ -984,7 +985,7 @@ rspamd_regexp_cache_create (struct rspamd_regexp_cache *cache, rspamd_regexp_t *res; if (cache == NULL) { - rspamd_regexp_library_init (); + rspamd_regexp_library_init (NULL); cache = global_re_cache; } @@ -1013,7 +1014,7 @@ void rspamd_regexp_cache_insert (struct rspamd_regexp_cache* cache, g_assert (pattern != NULL); if (cache == NULL) { - rspamd_regexp_library_init (); + rspamd_regexp_library_init (NULL); cache = global_re_cache; } @@ -1048,58 +1049,65 @@ rspamd_regexp_cache_destroy (struct rspamd_regexp_cache *cache) } void -rspamd_regexp_library_init (void) +rspamd_regexp_library_init (struct rspamd_config *cfg) { + if (cfg) { + if (cfg->disable_pcre_jit) { + can_jit = FALSE; + check_jit = FALSE; + } + } + if (global_re_cache == NULL) { global_re_cache = rspamd_regexp_cache_new (); #ifdef HAVE_PCRE_JIT gint jit, rc; gchar *str; + if (check_jit) { #ifdef WITH_PCRE2 - pcre2_ctx = pcre2_compile_context_create (NULL); - pcre2_set_newline (pcre2_ctx, PCRE_FLAG(NEWLINE_ANY)); + pcre2_ctx = pcre2_compile_context_create (NULL); + pcre2_set_newline (pcre2_ctx, PCRE_FLAG(NEWLINE_ANY)); #endif #ifndef WITH_PCRE2 - rc = pcre_config (PCRE_CONFIG_JIT, &jit); + rc = pcre_config (PCRE_CONFIG_JIT, &jit); #else - rc = pcre2_config (PCRE2_CONFIG_JIT, &jit); + rc = pcre2_config (PCRE2_CONFIG_JIT, &jit); #endif - if (rc == 0 && jit == 1) { + if (rc == 0 && jit == 1) { #ifndef WITH_PCRE2 #ifdef PCRE_CONFIG_JITTARGET - pcre_config (PCRE_CONFIG_JITTARGET, &str); - msg_info ("pcre is compiled with JIT for %s", str); + pcre_config (PCRE_CONFIG_JITTARGET, &str); + msg_info ("pcre is compiled with JIT for %s", str); #else - msg_info ("pcre is compiled with JIT for unknown target"); + msg_info ("pcre is compiled with JIT for unknown target"); #endif #else - rc = pcre2_config (PCRE2_CONFIG_JITTARGET, NULL); + rc = pcre2_config (PCRE2_CONFIG_JITTARGET, NULL); - if (rc > 0) { - str = g_alloca (rc); - pcre2_config (PCRE2_CONFIG_JITTARGET, str); - msg_info ("pcre2 is compiled with JIT for %s", str); - } - else { - msg_info ("pcre2 is compiled with JIT for unknown"); - } + if (rc > 0) { + str = g_alloca (rc); + pcre2_config (PCRE2_CONFIG_JITTARGET, str); + msg_info ("pcre2 is compiled with JIT for %s", str); + } + else { + msg_info ("pcre2 is compiled with JIT for unknown"); + } #endif /* WITH_PCRE2 */ - if (getenv ("VALGRIND") == NULL) { - can_jit = TRUE; - } - else { - msg_info ("disabling PCRE jit as it does not play well with valgrind"); - can_jit = FALSE; + if (getenv ("VALGRIND") == NULL) { + can_jit = TRUE; + } else { + msg_info ("disabling PCRE jit as it does not play well with valgrind"); + can_jit = FALSE; + } + } else { + msg_info ("pcre is compiled without JIT support, so many optimizations" + " are impossible"); } } - else { - msg_info ("pcre is compiled without JIT support, so many optimizations" - " are impossible"); - } #else msg_info ("pcre is too old and has no JIT support, so many optimizations" " are impossible"); diff --git a/src/libutil/regexp.h b/src/libutil/regexp.h index c85276b71..6b1bd50f9 100644 --- a/src/libutil/regexp.h +++ b/src/libutil/regexp.h @@ -34,6 +34,8 @@ #define RSPAMD_REGEXP_FLAG_PCRE_ONLY (1 << 4) #define RSPAMD_REGEXP_FLAG_DISABLE_JIT (1 << 5) +struct rspamd_config; + typedef struct rspamd_regexp_s rspamd_regexp_t; struct rspamd_regexp_cache; struct rspamd_re_capture { @@ -250,7 +252,7 @@ gint rspamd_regexp_cmp (gconstpointer a, gconstpointer b); /** * Initialize superglobal regexp cache and library */ -void rspamd_regexp_library_init (void); +void rspamd_regexp_library_init (struct rspamd_config *cfg); /** * Cleanup internal library structures -- 2.39.5