Make sure we don't process TAG records from the flow multiple times and outside the flow lock.

remotes/origin/master-1.1.x
Victor Julien 14 years ago
parent 6384b39f18
commit f4aad76bb4

@ -328,6 +328,8 @@ void TagHandlePacket(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
DetectTagDataEntry *prev = NULL; DetectTagDataEntry *prev = NULL;
DetectTagDataEntry *iter = NULL; DetectTagDataEntry *iter = NULL;
DetectTagDataEntryList tdl; DetectTagDataEntryList tdl;
DetectTagDataEntryList *tde_src = NULL;
DetectTagDataEntryList *tde_dst = NULL;
unsigned int current_tags = SC_ATOMIC_GET(num_tags); unsigned int current_tags = SC_ATOMIC_GET(num_tags);
/* If there's no tag, get out of here */ /* If there's no tag, get out of here */
@ -379,7 +381,7 @@ void TagHandlePacket(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
p->flags |= PKT_HAS_TAG; p->flags |= PKT_HAS_TAG;
flag_added++; flag_added++;
} }
break; break;
case DETECT_TAG_METRIC_BYTES: case DETECT_TAG_METRIC_BYTES:
if (iter->bytes > iter->td->count) { if (iter->bytes > iter->td->count) {
/* tag expired */ /* tag expired */
@ -404,7 +406,7 @@ void TagHandlePacket(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
p->flags |= PKT_HAS_TAG; p->flags |= PKT_HAS_TAG;
flag_added++; flag_added++;
} }
break; break;
case DETECT_TAG_METRIC_SECONDS: case DETECT_TAG_METRIC_SECONDS:
/* last_ts handles this metric, but also a generic time based /* last_ts handles this metric, but also a generic time based
* expiration to prevent dead sessions/hosts */ * expiration to prevent dead sessions/hosts */
@ -431,7 +433,7 @@ void TagHandlePacket(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
p->flags |= PKT_HAS_TAG; p->flags |= PKT_HAS_TAG;
flag_added++; flag_added++;
} }
break; break;
} }
} }
@ -439,6 +441,8 @@ void TagHandlePacket(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
prev = iter; prev = iter;
iter = iter->next; iter = iter->next;
} }
iter = NULL;
} }
SCMutexUnlock(&p->flow->m); SCMutexUnlock(&p->flow->m);
} }
@ -452,9 +456,6 @@ void TagHandlePacket(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
tag_ctx->last_ts.tv_sec = ts.tv_sec; tag_ctx->last_ts.tv_sec = ts.tv_sec;
} }
DetectTagDataEntryList *tde_src = NULL;
DetectTagDataEntryList *tde_dst = NULL;
if (PKT_IS_IPV4(p)) { if (PKT_IS_IPV4(p)) {
tdl.ipv = 4; tdl.ipv = 4;
/* search tags for source */ /* search tags for source */
@ -475,194 +476,196 @@ void TagHandlePacket(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
tde_dst = TagHashSearch(tag_ctx, &tdl, p); tde_dst = TagHashSearch(tag_ctx, &tdl, p);
} }
if (tde_src != NULL) if (tde_src != NULL) {
iter = tde_src->header_entry; iter = tde_src->header_entry;
prev = NULL; prev = NULL;
while (iter != NULL) { while (iter != NULL) {
/* update counters */ /* update counters */
iter->last_ts.tv_sec = ts.tv_sec; iter->last_ts.tv_sec = ts.tv_sec;
iter->packets++; iter->packets++;
iter->bytes += GET_PKT_LEN(p); iter->bytes += GET_PKT_LEN(p);
/* If this packet triggered the rule with tag, we dont need /* If this packet triggered the rule with tag, we dont need
* to log it (the alert will log it) */ * to log it (the alert will log it) */
if (iter->first_time++ > 0 && iter->td != NULL) { if (iter->first_time++ > 0 && iter->td != NULL) {
/* Update metrics; remove if tag expired; and set alerts */ /* Update metrics; remove if tag expired; and set alerts */
switch (iter->td->metric) { switch (iter->td->metric) {
case DETECT_TAG_METRIC_PACKET: case DETECT_TAG_METRIC_PACKET:
if (iter->packets > iter->td->count) { if (iter->packets > iter->td->count) {
/* tag expired */ /* tag expired */
if (prev != NULL) { if (prev != NULL) {
tde = iter; tde = iter;
prev->next = iter->next; prev->next = iter->next;
iter = iter->next; iter = iter->next;
DetectTagDataEntryFree(tde); DetectTagDataEntryFree(tde);
continue; continue;
} else { } else {
tde = iter; tde = iter;
iter = iter->next; iter = iter->next;
SCFree(tde); SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1); SC_ATOMIC_SUB(num_tags, 1);
tde_src->header_entry = NULL; tde_src->header_entry = NULL;
continue; continue;
} }
} else if (flag_added == 0) { } else if (flag_added == 0) {
/* It's matching the tag. Add it to be logged and /* It's matching the tag. Add it to be logged and
* update "flag_added" to add the packet once. */ * update "flag_added" to add the packet once. */
p->flags |= PKT_HAS_TAG; p->flags |= PKT_HAS_TAG;
flag_added++; flag_added++;
}
break;
case DETECT_TAG_METRIC_BYTES:
if (iter->bytes > iter->td->count) {
/* tag expired */
if (prev != NULL) {
tde = iter;
prev->next = iter->next;
iter = iter->next;
DetectTagDataEntryFree(tde);
continue;
} else {
tde = iter;
iter = iter->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
tde_src->header_entry = NULL;
continue;
} }
} else if (flag_added == 0) { break;
case DETECT_TAG_METRIC_BYTES:
if (iter->bytes > iter->td->count) {
/* tag expired */
if (prev != NULL) {
tde = iter;
prev->next = iter->next;
iter = iter->next;
DetectTagDataEntryFree(tde);
continue;
} else {
tde = iter;
iter = iter->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
tde_src->header_entry = NULL;
continue;
}
} else if (flag_added == 0) {
/* It's matching the tag. Add it to be logged and /* It's matching the tag. Add it to be logged and
* update "flag_added" to add the packet once. */ * update "flag_added" to add the packet once. */
p->flags |= PKT_HAS_TAG; p->flags |= PKT_HAS_TAG;
flag_added++; flag_added++;
}
break;
case DETECT_TAG_METRIC_SECONDS:
/* last_ts handles this metric, but also a generic time based
* expiration to prevent dead sessions/hosts */
if (iter->last_ts.tv_sec - iter->first_ts.tv_sec > (int)iter->td->count) {
/* tag expired */
if (prev != NULL) {
tde = iter;
prev->next = iter->next;
iter = iter->next;
DetectTagDataEntryFree(tde);
continue;
} else {
tde = iter;
iter = iter->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
tde_src->header_entry = NULL;
continue;
} }
} else if (flag_added == 0) { break;
case DETECT_TAG_METRIC_SECONDS:
/* last_ts handles this metric, but also a generic time based
* expiration to prevent dead sessions/hosts */
if (iter->last_ts.tv_sec - iter->first_ts.tv_sec > (int)iter->td->count) {
/* tag expired */
if (prev != NULL) {
tde = iter;
prev->next = iter->next;
iter = iter->next;
DetectTagDataEntryFree(tde);
continue;
} else {
tde = iter;
iter = iter->next;
SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1);
tde_src->header_entry = NULL;
continue;
}
} else if (flag_added == 0) {
/* It's matching the tag. Add it to be logged and /* It's matching the tag. Add it to be logged and
* update "flag_added" to add the packet once. */ * update "flag_added" to add the packet once. */
p->flags |= PKT_HAS_TAG; p->flags |= PKT_HAS_TAG;
flag_added++; flag_added++;
} }
break; break;
} }
}
prev = iter;
iter = iter->next;
} }
prev = iter;
iter = iter->next;
} }
if (tde_dst != NULL) if (tde_dst != NULL) {
iter = tde_dst->header_entry; iter = tde_dst->header_entry;
prev = NULL; prev = NULL;
while (iter != NULL) { while (iter != NULL) {
/* update counters */ /* update counters */
iter->last_ts.tv_sec = ts.tv_sec; iter->last_ts.tv_sec = ts.tv_sec;
iter->packets++; iter->packets++;
iter->bytes += GET_PKT_LEN(p); iter->bytes += GET_PKT_LEN(p);
/* If this packet triggered the rule with tag, we dont need /* If this packet triggered the rule with tag, we dont need
* to log it (the alert will log it) */ * to log it (the alert will log it) */
if (iter->first_time++ > 0 && iter->td != NULL) { if (iter->first_time++ > 0 && iter->td != NULL) {
/* Update metrics; remove if tag expired; and set alerts */ /* Update metrics; remove if tag expired; and set alerts */
switch (iter->td->metric) { switch (iter->td->metric) {
case DETECT_TAG_METRIC_PACKET: case DETECT_TAG_METRIC_PACKET:
if (iter->packets > iter->td->count) { if (iter->packets > iter->td->count) {
/* tag expired */ /* tag expired */
if (prev != NULL) { if (prev != NULL) {
tde = iter; tde = iter;
prev->next = iter->next; prev->next = iter->next;
iter = iter->next; iter = iter->next;
DetectTagDataEntryFree(tde); DetectTagDataEntryFree(tde);
continue; continue;
} else { } else {
tde = iter; tde = iter;
iter = iter->next; iter = iter->next;
SCFree(tde); SCFree(tde);
SC_ATOMIC_SUB(num_tags, 1); SC_ATOMIC_SUB(num_tags, 1);
tde_dst->header_entry = NULL; tde_dst->header_entry = NULL;
continue; continue;
}
} else if (flag_added == 0) {
/* It's matching the tag. Add it to be logged and
* update "flag_added" to add the packet once. */
p->flags |= PKT_HAS_TAG;
flag_added++;
} }
} else if (flag_added == 0) { break;
/* It's matching the tag. Add it to be logged and case DETECT_TAG_METRIC_BYTES:
* update "flag_added" to add the packet once. */ if (iter->bytes > iter->td->count) {
p->flags |= PKT_HAS_TAG; /* tag expired */
flag_added++; if (prev != NULL) {
} tde = iter;
break; prev->next = iter->next;
case DETECT_TAG_METRIC_BYTES: iter = iter->next;
if (iter->bytes > iter->td->count) { DetectTagDataEntryFree(tde);
/* tag expired */ continue;
if (prev != NULL) { } else {
tde = iter; tde = iter;
prev->next = iter->next; iter = iter->next;
iter = iter->next; SCFree(tde);
DetectTagDataEntryFree(tde); SC_ATOMIC_SUB(num_tags, 1);
continue; tde_dst->header_entry = NULL;
} else { continue;
tde = iter; }
iter = iter->next; } else if (flag_added == 0) {
SCFree(tde); /* It's matching the tag. Add it to be logged and
SC_ATOMIC_SUB(num_tags, 1); * update "flag_added" to add the packet once. */
tde_dst->header_entry = NULL; p->flags |= PKT_HAS_TAG;
continue; flag_added++;
} }
} else if (flag_added == 0) { break;
/* It's matching the tag. Add it to be logged and case DETECT_TAG_METRIC_SECONDS:
* update "flag_added" to add the packet once. */ /* last_ts handles this metric, but also a generic time based
p->flags |= PKT_HAS_TAG; * expiration to prevent dead sessions/hosts */
flag_added++; if (iter->last_ts.tv_sec - iter->first_ts.tv_sec > (int)iter->td->count) {
} /* tag expired */
break; if (prev != NULL) {
case DETECT_TAG_METRIC_SECONDS: tde = iter;
/* last_ts handles this metric, but also a generic time based prev->next = iter->next;
* expiration to prevent dead sessions/hosts */ iter = iter->next;
if (iter->last_ts.tv_sec - iter->first_ts.tv_sec > (int)iter->td->count) { DetectTagDataEntryFree(tde);
/* tag expired */ continue;
if (prev != NULL) { } else {
tde = iter; tde = iter;
prev->next = iter->next; iter = iter->next;
iter = iter->next; SCFree(tde);
DetectTagDataEntryFree(tde); SC_ATOMIC_SUB(num_tags, 1);
continue; tde_dst->header_entry = NULL;
} else { continue;
tde = iter; }
iter = iter->next; } else if (flag_added == 0) {
SCFree(tde); /* It's matching the tag. Add it to be logged and
SC_ATOMIC_SUB(num_tags, 1); * update "flag_added" to add the packet once. */
tde_dst->header_entry = NULL; p->flags |= PKT_HAS_TAG;
continue; flag_added++;
} }
} else if (flag_added == 0) { break;
/* It's matching the tag. Add it to be logged and }
* update "flag_added" to add the packet once. */
p->flags |= PKT_HAS_TAG;
flag_added++;
}
break;
} }
}
prev = iter; prev = iter;
iter = iter->next; iter = iter->next;
}
} }
SCMutexUnlock(&tag_ctx->lock); SCMutexUnlock(&tag_ctx->lock);

Loading…
Cancel
Save