]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
Rose: add handling for unexpected programs
authorWang, Xiang W <xiang.w.wang@intel.com>
Mon, 25 Mar 2019 16:30:07 +0000 (12:30 -0400)
committerWang Xiang W <xiang.w.wang@intel.com>
Tue, 26 Mar 2019 14:16:26 +0000 (10:16 -0400)
src/hs_common.h
src/rose/program_runtime.c
src/runtime.c
src/scratch.h

index 67aedb807dcb78e4d06a2d75e6c211babaf5bb76..93dc1fe8a1c35c871315be6acf34b176f8f4e5d7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, Intel Corporation
+ * Copyright (c) 2015-2019, Intel Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -577,6 +577,16 @@ hs_error_t HS_CDECL hs_valid_platform(void);
  */
 #define HS_INSUFFICIENT_SPACE   (-12)
 
+/**
+ * Unexpected internal error.
+ *
+ * This error indicates that there was unexpected matching behaviors. This
+ * could be related to invalid usage of stream and scratch space or invalid memory
+ * operations by users.
+ *
+ */
+#define HS_UNKNOWN_ERROR   (-13)
+
 /** @} */
 
 #ifdef __cplusplus
index 5a7f786ed81ffb2a53eb5c85e95fe5a731fc323f..97101e644aa7e9d4ff91a0cccbae6c1f71c1a529 100644 (file)
@@ -2771,6 +2771,12 @@ hwlmcb_rv_t roseRunProgram(const struct RoseEngine *t,
                 work_done = 1;
             }
             PROGRAM_NEXT_INSTRUCTION
+
+            default: {
+                assert(0); // unreachable
+                scratch->core_info.status |= STATUS_ERROR;
+                return HWLM_TERMINATE_MATCHING;
+            }
         }
     }
 
@@ -3053,6 +3059,8 @@ hwlmcb_rv_t roseRunProgram_l(const struct RoseEngine *t,
 
             default: {
                 assert(0); // unreachable
+                scratch->core_info.status |= STATUS_ERROR;
+                return HWLM_TERMINATE_MATCHING;
             }
         }
     }
index 68f1f8a752fc0d203008bf0792be2b3018f1a2b5..9a42dafb1ca0e03d5ec21f414c42378215c8f505 100644 (file)
@@ -151,7 +151,7 @@ void populateCoreInfo(struct hs_scratch *s, const struct RoseEngine *rose,
 }
 
 #define STATUS_VALID_BITS                                                      \
-    (STATUS_TERMINATED | STATUS_EXHAUSTED | STATUS_DELAY_DIRTY)
+    (STATUS_TERMINATED | STATUS_EXHAUSTED | STATUS_DELAY_DIRTY | STATUS_ERROR)
 
 /** \brief Retrieve status bitmask from stream state. */
 static really_inline
@@ -428,7 +428,10 @@ hs_error_t HS_CDECL hs_scan(const hs_database_t *db, const char *data,
     }
 
 done_scan:
-    if (told_to_stop_matching(scratch)) {
+    if (unlikely(internal_matching_error(scratch))) {
+        unmarkScratchInUse(scratch);
+        return HS_UNKNOWN_ERROR;
+    } else if (told_to_stop_matching(scratch)) {
         unmarkScratchInUse(scratch);
         return HS_SCAN_TERMINATED;
     }
@@ -447,6 +450,11 @@ done_scan:
     }
 
 set_retval:
+    if (unlikely(internal_matching_error(scratch))) {
+        unmarkScratchInUse(scratch);
+        return HS_UNKNOWN_ERROR;
+    }
+
     if (rose->flushCombProgramOffset) {
         if (roseRunFlushCombProgram(rose, scratch, ~0ULL) == MO_HALT_MATCHING) {
             unmarkScratchInUse(scratch);
@@ -626,7 +634,7 @@ void report_eod_matches(hs_stream_t *id, hs_scratch_t *scratch,
     char *state = getMultiState(id);
     u8 status = getStreamStatus(state);
 
-    if (status & (STATUS_TERMINATED | STATUS_EXHAUSTED)) {
+    if (status & (STATUS_TERMINATED | STATUS_EXHAUSTED | STATUS_ERROR)) {
         DEBUG_PRINTF("stream is broken, just freeing storage\n");
         return;
     }
@@ -749,6 +757,9 @@ hs_error_t HS_CDECL hs_reset_and_copy_stream(hs_stream_t *to_id,
         }
         report_eod_matches(to_id, scratch, onEvent, context);
         unmarkScratchInUse(scratch);
+        if (unlikely(internal_matching_error(scratch))) {
+            return HS_UNKNOWN_ERROR;
+        }
     }
 
     size_t stateSize
@@ -863,9 +874,11 @@ hs_error_t hs_scan_stream_internal(hs_stream_t *id, const char *data,
     char *state = getMultiState(id);
 
     u8 status = getStreamStatus(state);
-    if (status & (STATUS_TERMINATED | STATUS_EXHAUSTED)) {
+    if (status & (STATUS_TERMINATED | STATUS_EXHAUSTED | STATUS_ERROR)) {
         DEBUG_PRINTF("stream is broken, halting scan\n");
-        if (status & STATUS_TERMINATED) {
+        if (status & STATUS_ERROR) {
+            return HS_UNKNOWN_ERROR;
+        } else if (status & STATUS_TERMINATED) {
             return HS_SCAN_TERMINATED;
         } else {
             return HS_SUCCESS;
@@ -937,7 +950,9 @@ hs_error_t hs_scan_stream_internal(hs_stream_t *id, const char *data,
 
     setStreamStatus(state, scratch->core_info.status);
 
-    if (likely(!can_stop_matching(scratch))) {
+    if (unlikely(internal_matching_error(scratch))) {
+        return HS_UNKNOWN_ERROR;
+    } else if (likely(!can_stop_matching(scratch))) {
         maintainHistoryBuffer(rose, state, data, length);
         id->offset += length; /* maintain offset */
 
@@ -987,6 +1002,9 @@ hs_error_t HS_CDECL hs_close_stream(hs_stream_t *id, hs_scratch_t *scratch,
         }
         report_eod_matches(id, scratch, onEvent, context);
         unmarkScratchInUse(scratch);
+        if (unlikely(internal_matching_error(scratch))) {
+            return HS_UNKNOWN_ERROR;
+        }
     }
 
     if (id->rose->flushCombProgramOffset && !told_to_stop_matching(scratch)) {
@@ -1019,6 +1037,9 @@ hs_error_t HS_CDECL hs_reset_stream(hs_stream_t *id, UNUSED unsigned int flags,
         }
         report_eod_matches(id, scratch, onEvent, context);
         unmarkScratchInUse(scratch);
+        if (unlikely(internal_matching_error(scratch))) {
+            return HS_UNKNOWN_ERROR;
+        }
     }
 
     if (id->rose->flushCombProgramOffset && !told_to_stop_matching(scratch)) {
@@ -1139,7 +1160,10 @@ hs_error_t HS_CDECL hs_scan_vector(const hs_database_t *db,
     if (onEvent) {
         report_eod_matches(id, scratch, onEvent, context);
 
-        if (told_to_stop_matching(scratch)) {
+        if (unlikely(internal_matching_error(scratch))) {
+            unmarkScratchInUse(scratch);
+            return HS_UNKNOWN_ERROR;
+        } else if (told_to_stop_matching(scratch)) {
             unmarkScratchInUse(scratch);
             return HS_SCAN_TERMINATED;
         }
@@ -1238,6 +1262,9 @@ hs_error_t HS_CDECL hs_reset_and_expand_stream(hs_stream_t *to_stream,
         }
         report_eod_matches(to_stream, scratch, onEvent, context);
         unmarkScratchInUse(scratch);
+        if (unlikely(internal_matching_error(scratch))) {
+            return HS_UNKNOWN_ERROR;
+        }
     }
 
     if (expand_stream(to_stream, rose, buf, buf_size)) {
index dab7bab76d7c556f01416781742ee12172d63cb7..e2e8039a1379d19d8ff2ba69f023909ecb31129d 100644 (file)
@@ -84,6 +84,9 @@ struct catchup_pq {
  * history. */
 #define STATUS_DELAY_DIRTY  (1U << 2)
 
+/** \brief Status flag: Unexpected Rose program error. */
+#define STATUS_ERROR        (1U << 3)
+
 /** \brief Core information about the current scan, used everywhere. */
 struct core_info {
     void *userContext; /**< user-supplied context */
@@ -229,7 +232,13 @@ char told_to_stop_matching(const struct hs_scratch *scratch) {
 
 static really_inline
 char can_stop_matching(const struct hs_scratch *scratch) {
-    return scratch->core_info.status & (STATUS_TERMINATED | STATUS_EXHAUSTED);
+    return scratch->core_info.status &
+           (STATUS_TERMINATED | STATUS_EXHAUSTED | STATUS_ERROR);
+}
+
+static really_inline
+char internal_matching_error(const struct hs_scratch *scratch) {
+    return scratch->core_info.status & STATUS_ERROR;
 }
 
 /**