From 6dc9bed3107f38be95b73ed17c3373db87a8a745 Mon Sep 17 00:00:00 2001 From: "Wang, Xiang W" Date: Mon, 25 Mar 2019 12:30:07 -0400 Subject: [PATCH] Rose: add handling for unexpected programs --- src/hs_common.h | 12 ++++++++++- src/rose/program_runtime.c | 8 ++++++++ src/runtime.c | 41 +++++++++++++++++++++++++++++++------- src/scratch.h | 11 +++++++++- 4 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/hs_common.h b/src/hs_common.h index 67aedb80..93dc1fe8 100644 --- a/src/hs_common.h +++ b/src/hs_common.h @@ -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 diff --git a/src/rose/program_runtime.c b/src/rose/program_runtime.c index 5a7f786e..97101e64 100644 --- a/src/rose/program_runtime.c +++ b/src/rose/program_runtime.c @@ -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; } } } diff --git a/src/runtime.c b/src/runtime.c index 68f1f8a7..9a42dafb 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -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)) { diff --git a/src/scratch.h b/src/scratch.h index dab7bab7..e2e8039a 100644 --- a/src/scratch.h +++ b/src/scratch.h @@ -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; } /**