Skip to content

Commit 8a5e8c6

Browse files
committed
detect: strict validation of buffers
Make sure that every buffer in a signature is actually used in the setup of the engines. Reject sigs that are locked to a certain substate and use buffers that require another.
1 parent 89baff0 commit 8a5e8c6

1 file changed

Lines changed: 33 additions & 5 deletions

File tree

src/detect-parse.c

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2858,21 +2858,42 @@ static int SigValidateCheckBuffers(
28582858
SCReturnInt(0);
28592859
}
28602860

2861+
uint32_t app_buffers_evaluated = 0;
2862+
bool buffer_consumed = false;
2863+
uint32_t buffer_skip_alproto = 0;
2864+
uint32_t buffer_skip_substate = 0;
28612865
const DetectEngineAppInspectionEngine *app = de_ctx->app_inspect_engines;
28622866
for (; app != NULL; app = app->next) {
28632867
if (app->sm_list != b->id)
28642868
continue;
2869+
app_buffers_evaluated++;
28652870

28662871
if (s->init_data->hook.type == SIGNATURE_HOOK_TYPE_APP) {
28672872
/* only allow rules to use the hook for engines at that
2868-
* exact progress for now. */
2869-
if (!(AppProtoEqualsStrict(s->alproto, app->alproto))) {
2873+
* exact progress for now. We make an exception for generic
2874+
* engines like app-layer-event. */
2875+
if (!(AppProtoEqualsStrict(s->alproto, app->alproto) ||
2876+
app->alproto == ALPROTO_UNKNOWN)) {
2877+
SCLogDebug("%u:%s: for buffer %s skip engine %s alproto %s", s->id,
2878+
AppProtoToString(s->alproto), bt->name,
2879+
DetectEngineBufferTypeGetNameById(de_ctx, app->sm_list),
2880+
AppProtoToString(app->alproto));
2881+
buffer_skip_alproto++;
28702882
continue;
28712883
}
2872-
if (app->sub_state != s->init_data->hook.t.app.sub_state)
2884+
if (app->alproto != ALPROTO_UNKNOWN &&
2885+
app->sub_state != s->init_data->hook.t.app.sub_state) {
2886+
buffer_skip_substate++;
28732887
continue;
2888+
}
28742889
} else {
2875-
if (!(AppProtoEquals(s->alproto, app->alproto) || s->alproto == 0)) {
2890+
if (!(AppProtoEquals(s->alproto, app->alproto) || s->alproto == ALPROTO_UNKNOWN ||
2891+
app->alproto == ALPROTO_UNKNOWN)) {
2892+
SCLogDebug("%u:%s: for buffer %s skip engine %s alproto %s", s->id,
2893+
AppProtoToString(s->alproto), bt->name,
2894+
DetectEngineBufferTypeGetNameById(de_ctx, app->sm_list),
2895+
AppProtoToString(app->alproto));
2896+
buffer_skip_alproto++;
28762897
continue;
28772898
}
28782899
}
@@ -2906,8 +2927,15 @@ static int SigValidateCheckBuffers(
29062927
SCReturnInt(0);
29072928
}
29082929
}
2909-
}
29102930

2931+
buffer_consumed = true;
2932+
}
2933+
if (app_buffers_evaluated && !buffer_consumed) {
2934+
SCLogError("incompatible rule conditions, skipped buffer %s, reasons: app proto %u sub "
2935+
"state %u",
2936+
bt->name, buffer_skip_alproto, buffer_skip_substate);
2937+
SCReturnInt(0);
2938+
}
29112939
if (!DetectEngineBufferRunValidateCallback(de_ctx, b->id, s, &de_ctx->sigerror)) {
29122940
SCReturnInt(0);
29132941
}

0 commit comments

Comments
 (0)