]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
Bug 1098: improve invalid pcre/R handling 987/head
authorVictor Julien <victor@inliniac.net>
Tue, 10 Jun 2014 15:31:28 +0000 (17:31 +0200)
committerVictor Julien <victor@inliniac.net>
Tue, 10 Jun 2014 15:31:28 +0000 (17:31 +0200)
When not using a file_data or similar 'sticky buffer', a pcre/R option
needs a content in the same buffer.

src/detect-pcre.c

index ff45b9245b89bf9155cdff47c7d4c12b287cd253..c3261299589f1ae642dd5c116d46447142bbe0bd 100644 (file)
@@ -739,22 +739,29 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
     if (!(pd->flags & DETECT_PCRE_RELATIVE))
         goto okay;
 
+    /* errors below shouldn't free pd */
+
     SigMatch *prev_pm = SigMatchGetLastSMFromLists(s, 4,
                                                    DETECT_CONTENT, sm->prev,
                                                    DETECT_PCRE, sm->prev);
-    if (prev_pm == NULL)
+    if (s->list == DETECT_SM_LIST_NOTSET && prev_pm == NULL) {
+        SCLogError(SC_ERR_INVALID_SIGNATURE, "pcre with /R (relative) needs "
+                "preceeding match in the same buffer");
+        goto error_nofree;
+    /* null is allowed when we use a sticky buffer */
+    } else if (prev_pm == NULL)
         goto okay;
     if (prev_pm->type == DETECT_CONTENT) {
         DetectContentData *cd = (DetectContentData *)prev_pm->ctx;
         cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
     } else if (prev_pm->type == DETECT_PCRE) {
-        DetectPcreData *pd = (DetectPcreData *)prev_pm->ctx;
-        pd->flags |= DETECT_PCRE_RELATIVE_NEXT;
+        DetectPcreData *tmp = (DetectPcreData *)prev_pm->ctx;
+        tmp->flags |= DETECT_PCRE_RELATIVE_NEXT;
     }
 
     if (pd->capidx != 0) {
         if (DetectFlowvarPostMatchSetup(s, pd->capidx) < 0)
-            goto error;
+            goto error_nofree;
     }
 
  okay:
@@ -762,6 +769,7 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
     SCReturnInt(ret);
  error:
     DetectPcreFree(pd);
+ error_nofree:
     SCReturnInt(ret);
 }
 
@@ -1539,7 +1547,7 @@ int DetectPcreParseTest23(void)
                                "content:\"GET\"; "
                                "http_cookie; pcre:\"/abc/RM\"; sid:1;)");
 
-    if (de_ctx->sig_list != NULL) {
+    if (de_ctx->sig_list == NULL) {
         result = 1;
     } else {
         printf("sig parse shouldn't have failed: ");
@@ -1640,6 +1648,34 @@ static int DetectPcreParseTest26(void)
     return result;
 }
 
+/** \test Bug 1098 */
+static int DetectPcreParseTest27(void)
+{
+    DetectEngineCtx *de_ctx = NULL;
+    int result = 0;
+
+    if ( (de_ctx = DetectEngineCtxInit()) == NULL)
+        goto end;
+
+    de_ctx->flags |= DE_QUIET;
+    de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any 80 "
+            "(content:\"baduricontent\"; http_raw_uri; "
+            "pcre:\"/^[a-z]{5}\\.html/R\"; sid:2; rev:2;)");
+
+    if (de_ctx->sig_list == NULL) {
+        result = 1;
+    } else {
+        printf("sig parse should have failed: ");
+    }
+
+ end:
+    if (de_ctx != NULL)
+        SigCleanSignatures(de_ctx);
+    if (de_ctx != NULL)
+        DetectEngineCtxFree(de_ctx);
+    return result;
+}
+
 static int DetectPcreTestSig01Real(int mpm_type)
 {
     uint8_t *buf = (uint8_t *)
@@ -4049,6 +4085,7 @@ void DetectPcreRegisterTests(void) {
     UtRegisterTest("DetectPcreParseTest24", DetectPcreParseTest24, 1);
     UtRegisterTest("DetectPcreParseTest25", DetectPcreParseTest25, 1);
     UtRegisterTest("DetectPcreParseTest26", DetectPcreParseTest26, 1);
+    UtRegisterTest("DetectPcreParseTest27", DetectPcreParseTest27, 1);
 
     UtRegisterTest("DetectPcreTestSig01B2g -- pcre test", DetectPcreTestSig01B2g, 1);
     UtRegisterTest("DetectPcreTestSig01B3g -- pcre test", DetectPcreTestSig01B3g, 1);