mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-09-29 19:24:29 +03:00
Sync up branches/2.5.x and trunk.
This commit is contained in:
297
apache2/re.c
297
apache2/re.c
@@ -2,10 +2,18 @@
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2008 Breach Security, Inc. (http://www.breach.com/)
|
||||
*
|
||||
* You should have received a copy of the licence along with this
|
||||
* program (stored in the file "LICENSE"). If the file is missing,
|
||||
* or if you have any other questions related to the licence, please
|
||||
* write to Breach Security, Inc. at support@breach.com.
|
||||
* This product is released under the terms of the General Public Licence,
|
||||
* version 2 (GPLv2). Please refer to the file LICENSE (included with this
|
||||
* distribution) which contains the complete text of the licence.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL
|
||||
* as it is applied to this software. View the full text of the exception in
|
||||
* file MODSECURITY_LICENSING_EXCEPTION in the directory of this software
|
||||
* distribution.
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Breach Security, Inc.
|
||||
* directly using the email address support@breach.com.
|
||||
*
|
||||
*/
|
||||
#include <ctype.h>
|
||||
@@ -1774,7 +1782,7 @@ static apr_status_t msre_rule_process_normal(msre_rule *rule, modsec_rec *msr) {
|
||||
apr_pool_t *mptmp = msr->msc_rule_mptmp;
|
||||
apr_table_t *tartab = NULL;
|
||||
apr_table_t *vartab = NULL;
|
||||
int i, rc, match_count = 0;
|
||||
int i, rc = 0, match_count = 0;
|
||||
int invocations = 0;
|
||||
int multi_match = 0;
|
||||
|
||||
@@ -1789,6 +1797,7 @@ static apr_status_t msre_rule_process_normal(msre_rule *rule, modsec_rec *msr) {
|
||||
multi_match = 1;
|
||||
}
|
||||
|
||||
/* ENH: What is a good initial size? */
|
||||
tartab = apr_table_make(mptmp, 24);
|
||||
if (tartab == NULL) return -1;
|
||||
vartab = apr_table_make(mptmp, 24);
|
||||
@@ -1857,28 +1866,48 @@ static apr_status_t msre_rule_process_normal(msre_rule *rule, modsec_rec *msr) {
|
||||
for (i = 0; i < arr->nelts; i++) {
|
||||
int changed;
|
||||
int usecache = 0;
|
||||
apr_table_t **carr = NULL;
|
||||
apr_table_t *cachetab = NULL;
|
||||
apr_time_t time_before_trans = 0;
|
||||
msre_var *var;
|
||||
|
||||
/* Take one target. */
|
||||
msre_var *var = (msre_var *)te[i].val;
|
||||
var = (msre_var *)te[i].val;
|
||||
|
||||
/* Is this var cacheable? */
|
||||
if (msr->txcfg->cache_trans != MODSEC_CACHE_DISABLED) {
|
||||
usecache = 1;
|
||||
|
||||
/* Counting vars are not cacheable due to them being created
|
||||
* in a local per-rule pool.
|
||||
*/
|
||||
if (var->is_counting) {
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "CACHE: Disabled - &%s is dynamic", var->name);
|
||||
}
|
||||
|
||||
usecache = 0;
|
||||
}
|
||||
/* Only cache if if the variable is available in this phase */
|
||||
else if (msr->phase < var->metadata->availability) {
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "CACHE: Disabled - %s is not yet available in phase %d (requires phase %d or later)", var->name, msr->phase, var->metadata->availability);
|
||||
}
|
||||
|
||||
usecache = 0;
|
||||
}
|
||||
/* check the cache options */
|
||||
if (var->value_len < msr->txcfg->cache_trans_min) {
|
||||
else if (var->value_len < msr->txcfg->cache_trans_min) {
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "CACHE: Disabled - %s value length=%u, smaller than minlen=%" APR_SIZE_T_FMT, var->name, var->value_len, msr->txcfg->cache_trans_min);
|
||||
}
|
||||
|
||||
usecache = 0;
|
||||
}
|
||||
if ((msr->txcfg->cache_trans_max != 0) && (var->value_len > msr->txcfg->cache_trans_max)) {
|
||||
else if ((msr->txcfg->cache_trans_max != 0) && (var->value_len > msr->txcfg->cache_trans_max)) {
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "CACHE: Disabled - %s value length=%u, larger than maxlen=%" APR_SIZE_T_FMT, var->name, var->value_len, msr->txcfg->cache_trans_max);
|
||||
}
|
||||
|
||||
usecache = 0;
|
||||
}
|
||||
|
||||
@@ -1889,26 +1918,44 @@ static apr_status_t msre_rule_process_normal(msre_rule *rule, modsec_rec *msr) {
|
||||
msr_log(msr, 9, "CACHE: Enabled");
|
||||
}
|
||||
|
||||
#ifdef CACHE_DEBUG
|
||||
msr_log(msr, 9, "CACHE: Fetching cache entry from hash=%pp: %pp=%s", msr->tcache, var, var->name);
|
||||
#endif
|
||||
|
||||
/* Fetch cache table for this target */
|
||||
carr = (apr_table_t **)apr_hash_get(msr->tcache, var->name, APR_HASH_KEY_STRING);
|
||||
if (carr != NULL) {
|
||||
cachetab = carr[msr->phase];
|
||||
}
|
||||
else {
|
||||
/* Create an array of cache tables (one table per phase) */
|
||||
carr = (apr_table_t **)apr_pcalloc(msr->mp, (sizeof(apr_table_t *) * (PHASE_LAST + 1)));
|
||||
if (carr == NULL) return -1;
|
||||
memset(carr, 0, (sizeof(apr_table_t *) * (PHASE_LAST + 1)));
|
||||
apr_hash_set(msr->tcache, var->name, APR_HASH_KEY_STRING, carr);
|
||||
}
|
||||
cachetab = (apr_table_t *)apr_hash_get(msr->tcache, var->value, sizeof(var->value));
|
||||
|
||||
/* Create an empty cache table if this is the first time */
|
||||
if (cachetab == NULL) {
|
||||
cachetab = carr[msr->phase] = apr_table_make(msr->mp, 5);
|
||||
#ifdef CACHE_DEBUG
|
||||
if (cachetab) {
|
||||
msr_log(msr, 9, "CACHE: Using cache table %pp", cachetab);
|
||||
}
|
||||
else
|
||||
#else
|
||||
if (cachetab == NULL)
|
||||
#endif
|
||||
{
|
||||
/* NOTE: We use the pointer to the var value as a hash
|
||||
* key as it is unique. This pointer *must*
|
||||
* remain valid through the entire phase. If
|
||||
* it does not, then we will not receive a cache
|
||||
* hit and just wasted RAM. So, it is important
|
||||
* that any such vars be marked as VAR_DONT_CACHE.
|
||||
*
|
||||
* ENH: Only use pointer for non-scalar vars
|
||||
*/
|
||||
cachetab = apr_table_make(msr->mp, 3);
|
||||
apr_hash_set(msr->tcache, var->value, sizeof(var->value), cachetab);
|
||||
|
||||
#ifdef CACHE_DEBUG
|
||||
msr_log(msr, 9, "CACHE: Created a new cache table %pp for %pp", cachetab, var->value);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
usecache = 0;
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "CACHE: %s transformations are not cacheable", var->name);
|
||||
}
|
||||
@@ -1936,7 +1983,10 @@ static apr_status_t msre_rule_process_normal(msre_rule *rule, modsec_rec *msr) {
|
||||
msre_action *action;
|
||||
msre_tfn_metadata *metadata;
|
||||
apr_table_t *normtab;
|
||||
const char *lastvarval = NULL;
|
||||
apr_size_t lastvarlen = 0;
|
||||
|
||||
changed = 0;
|
||||
normtab = apr_table_make(mptmp, 10);
|
||||
if (normtab == NULL) return -1;
|
||||
tarr = apr_table_elts(rule->actionset->actions);
|
||||
@@ -1945,6 +1995,7 @@ static apr_status_t msre_rule_process_normal(msre_rule *rule, modsec_rec *msr) {
|
||||
/* Build the final list of transformation functions. */
|
||||
for (k = 0; k < tarr->nelts; k++) {
|
||||
action = (msre_action *)telts[k].val;
|
||||
|
||||
if (strcmp(telts[k].key, "t") == 0) {
|
||||
if (strcmp(action->param, "none") == 0) {
|
||||
apr_table_clear(normtab);
|
||||
@@ -1968,9 +2019,14 @@ static apr_status_t msre_rule_process_normal(msre_rule *rule, modsec_rec *msr) {
|
||||
* starting point
|
||||
*/
|
||||
if (usecache) {
|
||||
tfnspath = apr_psprintf(msr->mp, "%s%s%s", (tfnspath?tfnspath:""), (tfnspath?",":""), action->param);
|
||||
tfnskey = apr_psprintf(msr->mp, "%x;%s", tfnscount, tfnspath);
|
||||
tfnspath = apr_psprintf(mptmp, "%s%s%s", (tfnspath?tfnspath:""), (tfnspath?",":""), action->param);
|
||||
tfnskey = apr_psprintf(mptmp, "%x;%s", tfnscount, tfnspath);
|
||||
crec = (msre_cache_rec *)apr_table_get(cachetab, tfnskey);
|
||||
|
||||
#ifdef CACHE_DEBUG
|
||||
msr_log(msr, 9, "CACHE: %s %s cached=%d", var->name, tfnskey, (crec ? 1 : 0));
|
||||
#endif
|
||||
|
||||
if (crec != NULL) {
|
||||
last_crec = crec;
|
||||
last_cached_tfn = tfnscount;
|
||||
@@ -1983,15 +2039,19 @@ static apr_status_t msre_rule_process_normal(msre_rule *rule, modsec_rec *msr) {
|
||||
/* If the last cached tfn is the last in the list
|
||||
* then we can stop here and just execute the action immediatly
|
||||
*/
|
||||
if (usecache && !multi_match && (crec != NULL) && (crec == last_crec)) {
|
||||
if (usecache && !multi_match &&
|
||||
(crec != NULL) && (crec == last_crec))
|
||||
{
|
||||
crec->hits++;
|
||||
|
||||
if (crec->changed) {
|
||||
var->value = apr_pmemdup(msr->mp, crec->val, crec->val_len);
|
||||
var->value = apr_pmemdup(mptmp, crec->val, crec->val_len);
|
||||
var->value_len = crec->val_len;
|
||||
}
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "T (%d) %s: \"%s\" [cached hits=%d]", crec->changed, crec->path, log_escape_nq_ex(mptmp, var->value, var->value_len), crec->hits);
|
||||
msr_log(msr, 9, "T (%d) %s: \"%s\" [fully cached hits=%d]", crec->changed, crec->path,
|
||||
log_escape_nq_ex(mptmp, var->value, var->value_len), crec->hits);
|
||||
}
|
||||
|
||||
#if !defined(PERFORMANCE_MEASUREMENT)
|
||||
@@ -1999,9 +2059,11 @@ static apr_status_t msre_rule_process_normal(msre_rule *rule, modsec_rec *msr) {
|
||||
#endif
|
||||
{
|
||||
apr_time_t t1 = apr_time_now();
|
||||
|
||||
#if defined(PERFORMANCE_MEASUREMENT)
|
||||
rule->trans_time += (t1 - time_before_trans);
|
||||
#endif
|
||||
|
||||
msr_log(msr, 4, "Transformation completed in %" APR_TIME_T_FMT " usec.",
|
||||
(t1 - time_before_trans));
|
||||
}
|
||||
@@ -2030,14 +2092,6 @@ static apr_status_t msre_rule_process_normal(msre_rule *rule, modsec_rec *msr) {
|
||||
|
||||
tarr = apr_table_elts(normtab);
|
||||
|
||||
/* Make a copy of the variable value so that
|
||||
* we can change it in-place.
|
||||
*/
|
||||
if (tarr->nelts) {
|
||||
var->value = apr_pstrmemdup(mptmp, var->value, var->value_len);
|
||||
/* var->value_len remains the same */
|
||||
}
|
||||
|
||||
/* Execute transformations in a loop. */
|
||||
|
||||
/* Start after the last known cached transformation if we can */
|
||||
@@ -2046,32 +2100,39 @@ static apr_status_t msre_rule_process_normal(msre_rule *rule, modsec_rec *msr) {
|
||||
tfnspath = last_crec->path;
|
||||
last_crec->hits++;
|
||||
|
||||
if ((changed = last_crec->changed) == 1) {
|
||||
var->value = apr_pmemdup(msr->mp, last_crec->val, last_crec->val_len);
|
||||
if ((changed = last_crec->changed) > 0) {
|
||||
var->value = last_crec->val;
|
||||
var->value_len = last_crec->val_len;
|
||||
}
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "T (%d) %s: \"%s\" [partially cached hits=%d]", last_crec->changed, tfnspath, log_escape_nq_ex(mptmp, var->value, var->value_len), last_crec->hits);
|
||||
msr_log(msr, 9, "T (%d) %s: \"%s\" [partially cached hits=%d]", last_crec->changed,
|
||||
tfnspath, log_escape_nq_ex(mptmp, var->value, var->value_len), last_crec->hits);
|
||||
}
|
||||
}
|
||||
else {
|
||||
changed = 1;
|
||||
tfnspath = NULL;
|
||||
k = 0;
|
||||
}
|
||||
|
||||
/* Make a copy of the value so that we can change it in-place. */
|
||||
if (tarr->nelts) {
|
||||
var->value = apr_pstrmemdup(mptmp, var->value, var->value_len);
|
||||
/* var->value_len remains the same */
|
||||
}
|
||||
|
||||
telts = (const apr_table_entry_t*)tarr->elts;
|
||||
for (; k < tarr->nelts; k++) {
|
||||
char *rval = NULL;
|
||||
long int rval_length = -1;
|
||||
int tfnchanged = 0;
|
||||
|
||||
/* In multi-match mode we execute the operator
|
||||
* once at the beginning and then once every
|
||||
* time the variable is changed by the transformation
|
||||
* function.
|
||||
*/
|
||||
if (multi_match && changed) {
|
||||
if (multi_match && (k == 0 || tfnchanged)) {
|
||||
invocations++;
|
||||
|
||||
#if !defined(PERFORMANCE_MEASUREMENT)
|
||||
@@ -2079,9 +2140,11 @@ static apr_status_t msre_rule_process_normal(msre_rule *rule, modsec_rec *msr) {
|
||||
#endif
|
||||
{
|
||||
apr_time_t t1 = apr_time_now();
|
||||
|
||||
#if defined(PERFORMANCE_MEASUREMENT)
|
||||
rule->trans_time += (t1 - time_before_trans);
|
||||
#endif
|
||||
|
||||
msr_log(msr, 4, "Transformation completed in %" APR_TIME_T_FMT " usec.",
|
||||
(t1 - time_before_trans));
|
||||
}
|
||||
@@ -2108,60 +2171,88 @@ static apr_status_t msre_rule_process_normal(msre_rule *rule, modsec_rec *msr) {
|
||||
/* Perform one transformation. */
|
||||
action = (msre_action *)telts[k].val;
|
||||
metadata = (msre_tfn_metadata *)action->param_data;
|
||||
|
||||
/* Try to use the cache */
|
||||
if (usecache) {
|
||||
/* Generate the cache key */
|
||||
tfnspath = apr_psprintf(msr->mp, "%s%s%s", (tfnspath?tfnspath:""), (tfnspath?",":""), action->param);
|
||||
tfnskey = apr_psprintf(msr->mp, "%x;%s", (k + 1), tfnspath);
|
||||
|
||||
/* Try to fetch this transformation from cache */
|
||||
#ifdef CACHE_DEBUG
|
||||
msr_log(msr, 9, "CACHE: Fetching %s %s ", var->name, tfnskey);
|
||||
#endif
|
||||
crec = (msre_cache_rec *)apr_table_get(cachetab, tfnskey);
|
||||
if (crec != NULL) {
|
||||
crec->hits++;
|
||||
|
||||
if ((changed = crec->changed) == 1) {
|
||||
var->value = apr_pmemdup(msr->mp, crec->val, crec->val_len);
|
||||
var->value_len = crec->val_len;
|
||||
}
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "T (%d) %s: \"%s\" [cached hits=%d]", crec->changed, metadata->name, log_escape_nq_ex(mptmp, var->value, var->value_len), crec->hits);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
rc = metadata->execute(mptmp, (unsigned char *)var->value, var->value_len,
|
||||
tfnchanged = metadata->execute(mptmp,
|
||||
(unsigned char *)var->value, var->value_len,
|
||||
&rval, &rval_length);
|
||||
if (rc < 0) {
|
||||
|
||||
if (tfnchanged < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
changed = rc;
|
||||
if (tfnchanged) {
|
||||
changed++;
|
||||
}
|
||||
|
||||
/* Use the new values */
|
||||
var->value = rval;
|
||||
var->value_len = rval_length;
|
||||
|
||||
/* Cache the transformation */
|
||||
if (usecache) {
|
||||
/* ENH1: Add flag to vars to tell which ones can change across phases store the rest in a global cache */
|
||||
crec = (msre_cache_rec *)apr_pcalloc(msr->mp, sizeof(msre_cache_rec));
|
||||
if (crec == NULL) return -1;
|
||||
int tfnsnum = k + 1;
|
||||
|
||||
crec->hits = 0;
|
||||
crec->changed = changed;
|
||||
crec->num = k + 1;
|
||||
crec->path = tfnspath;
|
||||
crec->val = changed ? apr_pmemdup(msr->mp, var->value, var->value_len) : NULL;
|
||||
crec->val_len = changed ? var->value_len : 0;
|
||||
#ifdef CACHE_DEBUG
|
||||
msr_log(msr, 9, "CACHE: Caching %s=\"%.*s\"", tfnskey, var->value_len, log_escape_nq_ex(mptmp, var->value, var->value_len));
|
||||
#endif
|
||||
apr_table_setn(cachetab, tfnskey, (void *)crec);
|
||||
/* Generate the cache key */
|
||||
tfnspath = apr_psprintf(msr->mp, "%s%s%s", (tfnspath ? tfnspath : ""),
|
||||
(tfnspath ? "," : ""), action->param);
|
||||
tfnskey = apr_psprintf(msr->mp, "%x;%s", tfnsnum, tfnspath);
|
||||
|
||||
if ((msr->txcfg->cache_trans_maxitems != 0) &&
|
||||
(msr->tcache_items >= msr->txcfg->cache_trans_maxitems))
|
||||
{
|
||||
/* Warn only once if we attempt to go over the cache limit. */
|
||||
if (msr->tcache_items == msr->txcfg->cache_trans_maxitems) {
|
||||
msr->tcache_items++;
|
||||
msr_log(msr, 4, "CACHE: Disabled - phase=%d"
|
||||
" maxitems=%" APR_SIZE_T_FMT
|
||||
" limit reached.",
|
||||
msr->phase,
|
||||
msr->txcfg->cache_trans_maxitems);
|
||||
}
|
||||
}
|
||||
else if (msr->txcfg->cache_trans_incremental ||
|
||||
(tfnsnum == tarr->nelts))
|
||||
{
|
||||
/* ENH1: Add flag to vars to tell which ones can change across phases store the rest in a global cache */
|
||||
crec = (msre_cache_rec *)apr_pcalloc(msr->mp, sizeof(msre_cache_rec));
|
||||
if (crec == NULL) return -1;
|
||||
|
||||
crec->hits = 0;
|
||||
crec->changed = changed;
|
||||
crec->num = k + 1;
|
||||
crec->path = tfnspath;
|
||||
|
||||
/* We want to cache a copy if it changed otherwise
|
||||
* we just want to use a pointer to the last changed value.
|
||||
*/
|
||||
crec->val = (!lastvarval || tfnchanged) ? apr_pmemdup(msr->mp, var->value, var->value_len) : lastvarval;
|
||||
crec->val_len = changed ? ((!lastvarval || tfnchanged) ? var->value_len : lastvarlen) : 0;
|
||||
|
||||
/* Keep track of the last changed var value */
|
||||
if (tfnchanged) {
|
||||
lastvarval = crec->val;
|
||||
lastvarlen = crec->val_len;
|
||||
}
|
||||
|
||||
#ifdef CACHE_DEBUG
|
||||
if (changed) {
|
||||
msr_log(msr, 9, "CACHE: Caching %s=\"%s\" (%pp)",
|
||||
tfnskey,
|
||||
log_escape_nq_ex(mptmp,
|
||||
crec->val,
|
||||
crec->val_len),
|
||||
var);
|
||||
}
|
||||
else {
|
||||
msr_log(msr, 9, "CACHE: Caching %s=<no change> (%pp)",
|
||||
tfnskey,
|
||||
var);
|
||||
}
|
||||
#endif
|
||||
|
||||
msr->tcache_items++;
|
||||
|
||||
apr_table_setn(cachetab, tfnskey, (void *)crec);
|
||||
}
|
||||
}
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
@@ -2183,9 +2274,11 @@ static apr_status_t msre_rule_process_normal(msre_rule *rule, modsec_rec *msr) {
|
||||
#endif
|
||||
{
|
||||
apr_time_t t1 = apr_time_now();
|
||||
|
||||
#if defined(PERFORMANCE_MEASUREMENT)
|
||||
rule->trans_time += (t1 - time_before_trans);
|
||||
#endif
|
||||
|
||||
msr_log(msr, 4, "Transformation completed in %" APR_TIME_T_FMT " usec.",
|
||||
(t1 - time_before_trans));
|
||||
}
|
||||
@@ -2210,44 +2303,6 @@ static apr_status_t msre_rule_process_normal(msre_rule *rule, modsec_rec *msr) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CACHE_DEBUG
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
apr_hash_index_t *hi;
|
||||
void *dummy;
|
||||
apr_table_t **tab;
|
||||
const apr_array_header_t *ctarr;
|
||||
const apr_table_entry_t *ctelts;
|
||||
msre_cache_rec *rec;
|
||||
int cn = 0;
|
||||
int ti, ri;
|
||||
|
||||
for (hi = apr_hash_first(msr->mp, msr->tcache); hi; hi = apr_hash_next(hi)) {
|
||||
apr_hash_this(hi, NULL, NULL, &dummy);
|
||||
tab = (apr_table_t **)dummy;
|
||||
if (tab == NULL) continue;
|
||||
|
||||
for (ti = PHASE_FIRST; ti <= PHASE_LAST; ti++) {
|
||||
if (tab[ti] == NULL) continue;
|
||||
ctarr = apr_table_elts(tab[ti]);
|
||||
ctelts = (const apr_table_entry_t*)ctarr->elts;
|
||||
for (ri = 0; ri < ctarr->nelts; ri++) {
|
||||
cn++;
|
||||
rec = (msre_cache_rec *)ctelts[ri].val;
|
||||
if (rec->changed) {
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "CACHE: %5d) phase=%d hits=%d %x;%s=\"%s\"", cn, msr->phase, rec->hits, rec->num, rec->path, log_escape_nq_ex(mptmp, rec->val, rec->val_len));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "CACHE: %5d) phase=%d hits=%d %x;%s=<no change>", cn, msr->phase, rec->hits, rec->num, rec->path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return (match_count ? RULE_MATCH : RULE_NO_MATCH);
|
||||
}
|
||||
|
Reference in New Issue
Block a user