]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/parse: allow signature parsing to fail silently
authorVictor Julien <victor@inliniac.net>
Mon, 7 Oct 2019 13:50:09 +0000 (15:50 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 9 Oct 2019 13:26:59 +0000 (15:26 +0200)
A sigmatches 'Setup' function may indicate it intends to fail
silently after the first error. It will return -2 instead of -1
in this case.

This is tracked in the DetectEngineCtx object, so errors will
be shown again at rule reloads.

src/detect-engine-loader.c
src/detect-parse.c
src/detect-parse.h
src/detect.h

index b27bf7f999fa3a82d7522df5d2b3729006a99ddf..281be7945c73dcd7e0f27c902234f93eed51b341 100644 (file)
@@ -180,20 +180,22 @@ static int DetectLoadSigFile(DetectEngineCtx *de_ctx, char *sig_file,
             SCLogDebug("signature %"PRIu32" loaded", sig->id);
             good++;
         } else {
-            SCLogError(SC_ERR_INVALID_SIGNATURE, "error parsing signature \"%s\" from "
-                 "file %s at line %"PRId32"", line, sig_file, lineno - multiline);
+            if (!de_ctx->sigerror_silent) {
+                SCLogError(SC_ERR_INVALID_SIGNATURE, "error parsing signature \"%s\" from "
+                        "file %s at line %"PRId32"", line, sig_file, lineno - multiline);
 
+                if (!SigStringAppend(&de_ctx->sig_stat, sig_file, line, de_ctx->sigerror, (lineno - multiline))) {
+                    SCLogError(SC_ERR_MEM_ALLOC, "Error adding sig \"%s\" from "
+                            "file %s at line %"PRId32"", line, sig_file, lineno - multiline);
+                }
+                if (de_ctx->sigerror) {
+                    de_ctx->sigerror = NULL;
+                }
+            }
             if (rule_engine_analysis_set) {
                 EngineAnalysisRulesFailure(line, sig_file, lineno - multiline);
             }
             bad++;
-            if (!SigStringAppend(&de_ctx->sig_stat, sig_file, line, de_ctx->sigerror, (lineno - multiline))) {
-                SCLogError(SC_ERR_MEM_ALLOC, "Error adding sig \"%s\" from "
-                     "file %s at line %"PRId32"", line, sig_file, lineno - multiline);
-            }
-            if (de_ctx->sigerror) {
-                de_ctx->sigerror = NULL;
-            }
         }
         multiline = 0;
     }
index b910d0d7612ccce6e63c77745c53576470d4c30c..b03d3bfac342174ed7a754e6b5e459084e49880d 100644 (file)
@@ -258,6 +258,14 @@ void SigMatchFree(SigMatch *sm)
     SCFree(sm);
 }
 
+static enum DetectKeywordId SigTableGetIndex(const SigTableElmt *e)
+{
+    const SigTableElmt *table = &sigmatch_table[0];
+    ptrdiff_t offset = e - table;
+    BUG_ON(offset >= DETECT_TBLSIZE);
+    return (enum DetectKeywordId)offset;
+}
+
 /* Get the detection module by name */
 static SigTableElmt *SigTableGet(char *name)
 {
@@ -278,6 +286,12 @@ static SigTableElmt *SigTableGet(char *name)
     return NULL;
 }
 
+bool SigMatchSilentErrorEnabled(const DetectEngineCtx *de_ctx,
+        const enum DetectKeywordId id)
+{
+    return de_ctx->sm_types_silent_error[id];
+}
+
 bool SigMatchStrictEnabled(const enum DetectKeywordId id)
 {
     if (id < DETECT_TBLSIZE) {
@@ -792,7 +806,17 @@ static int SigParseOptions(DetectEngineCtx *de_ctx, Signature *s, char *optstr,
     }
     if (setup_ret < 0) {
         SCLogDebug("\"%s\" failed to setup", st->name);
-        goto error;
+
+        /* handle 'silent' error case */
+        if (setup_ret == -2) {
+            enum DetectKeywordId idx = SigTableGetIndex(st);
+            if (de_ctx->sm_types_silent_error[idx] == false) {
+                de_ctx->sm_types_silent_error[idx] = true;
+                return -1;
+            }
+            return -2;
+        }
+        return setup_ret;
     }
     s->init_data->negated = false;
 
@@ -1839,8 +1863,13 @@ static Signature *SigInitHelper(DetectEngineCtx *de_ctx, const char *sigstr,
     /* default gid to 1 */
     sig->gid = 1;
 
-    if (SigParse(de_ctx, sig, sigstr, dir, &parser) < 0)
+    int ret = SigParse(de_ctx, sig, sigstr, dir, &parser);
+    if (ret == -2) {
+        de_ctx->sigerror_silent = true;
+        goto error;
+    } else if (ret < 0) {
         goto error;
+    }
 
     /* signature priority hasn't been overwritten.  Using default priority */
     if (sig->prio == -1)
@@ -1982,6 +2011,7 @@ Signature *SigInit(DetectEngineCtx *de_ctx, const char *sigstr)
     SCEnter();
 
     uint32_t oldsignum = de_ctx->signum;
+    de_ctx->sigerror_silent = false;
 
     Signature *sig;
 
index a390abbe58d603c1ef5e20404c431d0ad1ecd644..aa89e5e2e9daef1994e6db0400254cdccca2bf3b 100644 (file)
@@ -59,6 +59,8 @@ int DetectEngineContentModifierBufferSetup(DetectEngineCtx *de_ctx,
         Signature *s, const char *arg, int sm_type, int sm_list,
         AppProto alproto);
 
+bool SigMatchSilentErrorEnabled(const DetectEngineCtx *de_ctx,
+        const enum DetectKeywordId id);
 bool SigMatchStrictEnabled(const enum DetectKeywordId id);
 
 const char *DetectListToHumanString(int list);
index 35d17f43a011b2174cf0adf87b7584706ee85ebf..0a895a8990ed9b058f3fac455ff41e5887cfecd3 100644 (file)
@@ -864,6 +864,7 @@ typedef struct DetectEngineCtx_ {
     /** Store rule file and line so that parsers can use them in errors. */
     char *rule_file;
     int rule_line;
+    bool sigerror_silent;
     const char *sigerror;
 
     /** list of keywords that need thread local ctxs */
@@ -943,6 +944,7 @@ typedef struct DetectEngineCtx_ {
      *  set for it. If true, the setup function will have to
      *  run. */
     bool sm_types_prefilter[DETECT_TBLSIZE];
+    bool sm_types_silent_error[DETECT_TBLSIZE];
 
 } DetectEngineCtx;