detect-state: rip per sig detect out of ContinueDetect

pull/1375/head
Victor Julien 11 years ago
parent bf818b8fb2
commit eec22ce19b

@ -466,81 +466,30 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
return alert_cnt ? 1:0; return alert_cnt ? 1:0;
} }
void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, static int DoInspectItem(ThreadVars *tv,
DetectEngineThreadCtx *det_ctx, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
Packet *p, Flow *f, uint8_t flags, const int alproto_supports_txs,
AppProto alproto, uint16_t alversion) DeStateStoreItem *item, const uint8_t dir_state_flags,
Packet *p, Flow *f, AppProto alproto, uint8_t flags,
const uint64_t inspect_tx_id, const uint64_t total_txs,
uint16_t *file_no_match)
{ {
DetectEngineAppInspectionEngine *engine = NULL;
SigMatch *sm = NULL;
uint16_t file_no_match = 0;
uint32_t inspect_flags = 0;
void *alstate = NULL;
SMBState *smb_state = NULL;
SigIntId store_cnt = 0;
SigIntId state_cnt = 0;
int match = 0;
uint8_t alert = 0;
void *inspect_tx = NULL;
uint64_t inspect_tx_id = 0;
uint64_t total_txs = 0;
uint8_t alproto_supports_txs = 0;
uint8_t reset_de_state = 0;
/* this was introduced later to allow protocols that had both app
* keywords with transaction keywords. Without this we would
* assume that we have an alert if engine == NULL */
uint8_t total_matches = 0;
SCMutexLock(&f->de_state_m);
DetectEngineStateDirection *dir_state = &f->de_state->dir_state[flags & STREAM_TOSERVER ? 0 : 1];
DeStateStore *store = dir_state->head;
if (AppLayerParserProtocolSupportsTxs(f->proto, alproto)) {
FLOWLOCK_RDLOCK(f);
alstate = FlowGetAppState(f);
if (!StateIsValid(alproto, alstate)) {
FLOWLOCK_UNLOCK(f);
SCMutexUnlock(&f->de_state_m);
return;
}
inspect_tx_id = AppLayerParserGetTransactionInspectId(f->alparser, flags);
total_txs = AppLayerParserGetTxCnt(f->proto, alproto, alstate);
inspect_tx = AppLayerParserGetTx(f->proto, alproto, alstate, inspect_tx_id);
if (inspect_tx != NULL) {
if (AppLayerParserGetStateProgress(f->proto, alproto, inspect_tx, flags) >=
AppLayerParserGetStateProgressCompletionStatus(f->proto, alproto, flags)) {
reset_de_state = 1;
}
}
FLOWLOCK_UNLOCK(f);
alproto_supports_txs = 1;
}
for (; store != NULL; store = store->next) {
for (store_cnt = 0;
store_cnt < DE_STATE_CHUNK_SIZE && state_cnt < dir_state->cnt;
store_cnt++, state_cnt++)
{
total_matches = 0;
DeStateStoreItem *item = &store->store[store_cnt];
Signature *s = de_ctx->sig_array[item->sid]; Signature *s = de_ctx->sig_array[item->sid];
/* check if a sig in state 'full inspect' needs to be reconsidered
* as the result of a new file in the existing tx */
if (item->flags & DE_STATE_FLAG_FULL_INSPECT) { if (item->flags & DE_STATE_FLAG_FULL_INSPECT) {
if (item->flags & (DE_STATE_FLAG_FILE_TC_INSPECT | if (item->flags & (DE_STATE_FLAG_FILE_TC_INSPECT|DE_STATE_FLAG_FILE_TS_INSPECT)) {
DE_STATE_FLAG_FILE_TS_INSPECT)) {
if ((flags & STREAM_TOCLIENT) && if ((flags & STREAM_TOCLIENT) &&
(dir_state->flags & DETECT_ENGINE_STATE_FLAG_FILE_TC_NEW)) (dir_state_flags & DETECT_ENGINE_STATE_FLAG_FILE_TC_NEW))
{ {
item->flags &= ~DE_STATE_FLAG_FILE_TC_INSPECT; item->flags &= ~DE_STATE_FLAG_FILE_TC_INSPECT;
item->flags &= ~DE_STATE_FLAG_FULL_INSPECT; item->flags &= ~DE_STATE_FLAG_FULL_INSPECT;
} }
if ((flags & STREAM_TOSERVER) && if ((flags & STREAM_TOSERVER) &&
(dir_state->flags & DETECT_ENGINE_STATE_FLAG_FILE_TS_NEW)) (dir_state_flags & DETECT_ENGINE_STATE_FLAG_FILE_TS_NEW))
{ {
item->flags &= ~DE_STATE_FLAG_FILE_TS_INSPECT; item->flags &= ~DE_STATE_FLAG_FILE_TS_INSPECT;
item->flags &= ~DE_STATE_FLAG_FULL_INSPECT; item->flags &= ~DE_STATE_FLAG_FULL_INSPECT;
@ -555,20 +504,22 @@ void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
} else { } else {
det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NO_NEW_STATE; det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NO_NEW_STATE;
} }
continue; return 0;
} }
} }
/* check if a sig in state 'cant match' needs to be reconsidered
* as the result of a new file in the existing tx */
if (item->flags & DE_STATE_FLAG_SIG_CANT_MATCH) { if (item->flags & DE_STATE_FLAG_SIG_CANT_MATCH) {
if ((flags & STREAM_TOSERVER) && if ((flags & STREAM_TOSERVER) &&
(item->flags & DE_STATE_FLAG_FILE_TS_INSPECT) && (item->flags & DE_STATE_FLAG_FILE_TS_INSPECT) &&
(dir_state->flags & DETECT_ENGINE_STATE_FLAG_FILE_TS_NEW)) (dir_state_flags & DETECT_ENGINE_STATE_FLAG_FILE_TS_NEW))
{ {
item->flags &= ~DE_STATE_FLAG_FILE_TS_INSPECT; item->flags &= ~DE_STATE_FLAG_FILE_TS_INSPECT;
item->flags &= ~DE_STATE_FLAG_SIG_CANT_MATCH; item->flags &= ~DE_STATE_FLAG_SIG_CANT_MATCH;
} else if ((flags & STREAM_TOCLIENT) && } else if ((flags & STREAM_TOCLIENT) &&
(item->flags & DE_STATE_FLAG_FILE_TC_INSPECT) && (item->flags & DE_STATE_FLAG_FILE_TC_INSPECT) &&
(dir_state->flags & DETECT_ENGINE_STATE_FLAG_FILE_TC_NEW)) (dir_state_flags & DETECT_ENGINE_STATE_FLAG_FILE_TC_NEW))
{ {
item->flags &= ~DE_STATE_FLAG_FILE_TC_INSPECT; item->flags &= ~DE_STATE_FLAG_FILE_TC_INSPECT;
item->flags &= ~DE_STATE_FLAG_SIG_CANT_MATCH; item->flags &= ~DE_STATE_FLAG_SIG_CANT_MATCH;
@ -580,40 +531,41 @@ void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
} else { } else {
det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NO_NEW_STATE; det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NO_NEW_STATE;
} }
continue; return 0;
} }
} }
alert = 0; uint8_t alert = 0;
inspect_flags = 0; uint32_t inspect_flags = 0;
match = 0; int total_matches = 0;
RULE_PROFILING_START(p); RULE_PROFILING_START(p);
if (alproto_supports_txs) { if (alproto_supports_txs) {
FLOWLOCK_WRLOCK(f); FLOWLOCK_WRLOCK(f);
alstate = FlowGetAppState(f); void *alstate = FlowGetAppState(f);
if (!StateIsValid(alproto, alstate)) { if (!StateIsValid(alproto, alstate)) {
FLOWLOCK_UNLOCK(f); FLOWLOCK_UNLOCK(f);
RULE_PROFILING_END(det_ctx, s, match, p); RULE_PROFILING_END(det_ctx, s, 0, p);
goto end; return -1;
} }
det_ctx->tx_id = inspect_tx_id; det_ctx->tx_id = inspect_tx_id;
det_ctx->tx_id_set = 1; det_ctx->tx_id_set = 1;
engine = app_inspection_engine[FlowGetProtoMapping(f->proto)][alproto][(flags & STREAM_TOSERVER) ? 0 : 1]; DetectEngineAppInspectionEngine *engine = app_inspection_engine[FlowGetProtoMapping(f->proto)][alproto][(flags & STREAM_TOSERVER) ? 0 : 1];
inspect_tx = AppLayerParserGetTx(f->proto, alproto, alstate, inspect_tx_id); void *inspect_tx = AppLayerParserGetTx(f->proto, alproto, alstate, inspect_tx_id);
if (inspect_tx == NULL) { if (inspect_tx == NULL) {
FLOWLOCK_UNLOCK(f); FLOWLOCK_UNLOCK(f);
RULE_PROFILING_END(det_ctx, s, match, p); RULE_PROFILING_END(det_ctx, s, 0, p);
goto end; return -1;
} }
while (engine != NULL) { while (engine != NULL) {
if (!(item->flags & engine->inspect_flags) && if (!(item->flags & engine->inspect_flags) &&
s->sm_lists[engine->sm_list] != NULL) s->sm_lists[engine->sm_list] != NULL)
{ {
KEYWORD_PROFILING_SET_LIST(det_ctx, engine->sm_list); KEYWORD_PROFILING_SET_LIST(det_ctx, engine->sm_list);
match = engine->Callback(tv, de_ctx, det_ctx, s, f, int match = engine->Callback(tv, de_ctx, det_ctx, s, f,
flags, alstate, inspect_tx, inspect_tx_id); flags, alstate, inspect_tx, inspect_tx_id);
if (match == DETECT_ENGINE_INSPECT_SIG_MATCH) { if (match == DETECT_ENGINE_INSPECT_SIG_MATCH) {
inspect_flags |= engine->inspect_flags; inspect_flags |= engine->inspect_flags;
@ -626,7 +578,7 @@ void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
} else if (match == DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILESTORE) { } else if (match == DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILESTORE) {
inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH; inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
inspect_flags |= engine->inspect_flags; inspect_flags |= engine->inspect_flags;
file_no_match++; (*file_no_match)++;
} }
break; break;
} }
@ -643,24 +595,26 @@ void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
/* count AMATCH matches */ /* count AMATCH matches */
total_matches = 0; total_matches = 0;
SigMatch *sm = NULL;
KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_AMATCH); KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_AMATCH);
if (item->nm != NULL) { if (item->nm != NULL) {
/* RDLOCK would be nicer, but at least tlsstore needs /* RDLOCK would be nicer, but at least tlsstore needs
* write lock currently. */ * write lock currently. */
FLOWLOCK_WRLOCK(f); FLOWLOCK_WRLOCK(f);
alstate = FlowGetAppState(f); void *alstate = FlowGetAppState(f);
if (alstate == NULL) { if (alstate == NULL) {
FLOWLOCK_UNLOCK(f); FLOWLOCK_UNLOCK(f);
RULE_PROFILING_END(det_ctx, s, 0 /* no match */, p); RULE_PROFILING_END(det_ctx, s, 0 /* no match */, p);
goto end; return -1;
} }
for (sm = item->nm; sm != NULL; sm = sm->next) { for (sm = item->nm; sm != NULL; sm = sm->next) {
if (sigmatch_table[sm->type].AppLayerMatch != NULL) if (sigmatch_table[sm->type].AppLayerMatch != NULL)
{ {
int match = 0;
if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) { if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
smb_state = (SMBState *)alstate; SMBState *smb_state = (SMBState *)alstate;
if (smb_state->dcerpc_present) { if (smb_state->dcerpc_present) {
KEYWORD_PROFILING_START; KEYWORD_PROFILING_START;
match = sigmatch_table[sm->type]. match = sigmatch_table[sm->type].
@ -684,7 +638,6 @@ void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
} }
FLOWLOCK_UNLOCK(f); FLOWLOCK_UNLOCK(f);
} }
RULE_PROFILING_END(det_ctx, s, match, p);
if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) { if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) {
if (total_matches > 0 && (sm == NULL || inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH)) { if (total_matches > 0 && (sm == NULL || inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH)) {
@ -694,6 +647,7 @@ void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
} }
det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NO_NEW_STATE; det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NO_NEW_STATE;
} }
RULE_PROFILING_END(det_ctx, s, (alert == 1), p);
item->flags |= inspect_flags; item->flags |= inspect_flags;
item->nm = sm; item->nm = sm;
@ -717,6 +671,64 @@ void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
} }
DetectFlowvarProcessList(det_ctx, f); DetectFlowvarProcessList(det_ctx, f);
return 1;
}
void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Packet *p, Flow *f, uint8_t flags,
AppProto alproto, uint16_t alversion)
{
uint16_t file_no_match = 0;
SigIntId store_cnt = 0;
SigIntId state_cnt = 0;
uint64_t inspect_tx_id = 0;
uint64_t total_txs = 0;
uint8_t alproto_supports_txs = 0;
uint8_t reset_de_state = 0;
SCMutexLock(&f->de_state_m);
DetectEngineStateDirection *dir_state = &f->de_state->dir_state[flags & STREAM_TOSERVER ? 0 : 1];
DeStateStore *store = dir_state->head;
if (AppLayerParserProtocolSupportsTxs(f->proto, alproto)) {
FLOWLOCK_RDLOCK(f);
void *alstate = FlowGetAppState(f);
if (!StateIsValid(alproto, alstate)) {
FLOWLOCK_UNLOCK(f);
SCMutexUnlock(&f->de_state_m);
return;
}
inspect_tx_id = AppLayerParserGetTransactionInspectId(f->alparser, flags);
total_txs = AppLayerParserGetTxCnt(f->proto, alproto, alstate);
void *inspect_tx = AppLayerParserGetTx(f->proto, alproto, alstate, inspect_tx_id);
if (inspect_tx != NULL) {
if (AppLayerParserGetStateProgress(f->proto, alproto, inspect_tx, flags) >=
AppLayerParserGetStateProgressCompletionStatus(f->proto, alproto, flags)) {
reset_de_state = 1;
}
}
FLOWLOCK_UNLOCK(f);
alproto_supports_txs = 1;
}
/* Loop through stored 'items' (stateful rules) and inspect them */
for (; store != NULL; store = store->next) {
for (store_cnt = 0;
store_cnt < DE_STATE_CHUNK_SIZE && state_cnt < dir_state->cnt;
store_cnt++, state_cnt++)
{
DeStateStoreItem *item = &store->store[store_cnt];
int r = DoInspectItem(tv, de_ctx, det_ctx, alproto_supports_txs,
item, dir_state->flags,
p, f, alproto, flags,
inspect_tx_id, total_txs,
&file_no_match);
if (r < 0) {
goto end;
}
} }
} }

Loading…
Cancel
Save