Catena cyber 23 hours ago committed by GitHub
commit f2527b7826
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1478,10 +1478,15 @@ void EngineAnalysisRules2(const DetectEngineCtx *de_ctx, const Signature *s)
SCJbSetString(ctx.js, "direction", direction); SCJbSetString(ctx.js, "direction", direction);
SCJbSetBool(ctx.js, "is_mpm", app->mpm); SCJbSetBool(ctx.js, "is_mpm", app->mpm);
SCJbSetString(ctx.js, "app_proto", AppProtoToString(app->alproto)); SCJbSetString(ctx.js, "app_proto", AppProtoToString(app->alproto));
SCJbSetUint(ctx.js, "progress", app->progress);
if (app->sub_state) if (app->sub_state)
SCJbSetString(ctx.js, "sub_state", SCJbSetString(ctx.js, "sub_state",
AppLayerParserGetSubStateName(app->alproto, app->sub_state)); AppLayerParserGetSubStateName(app->alproto, app->sub_state));
if (app->max_progress != app->min_progress) {
SCJbSetUint(ctx.js, "min_progress", app->min_progress);
SCJbSetUint(ctx.js, "max_progress", app->max_progress);
} else {
SCJbSetUint(ctx.js, "progress", app->min_progress);
}
if (app->v2.transforms != NULL) { if (app->v2.transforms != NULL) {
SCJbOpenArray(ctx.js, "transforms"); SCJbOpenArray(ctx.js, "transforms");

@ -1082,9 +1082,16 @@ static int SetupNonPrefilter(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
const bool run_always = buf != NULL && buf->run_always; const bool run_always = buf != NULL && buf->run_always;
const uint8_t sub_state = app->sub_state; const uint8_t sub_state = app->sub_state;
if (TxNonPFAddSig(de_ctx, tx_engines_hash, app->alproto, sub_state, app->dir, if (TxNonPFAddSig(de_ctx, tx_engines_hash, app->alproto, sub_state, app->dir,
app->progress, sig_list, buf->name, s, run_always) != 0) { app->min_progress, sig_list, buf->name, s, run_always) != 0) {
goto error; goto error;
} }
if (app->max_progress > app->min_progress) {
if (TxNonPFAddSig(de_ctx, tx_engines_hash, app->alproto, sub_state,
app->dir, app->max_progress, sig_list, buf->name, s,
run_always) != 0) {
goto error;
}
}
tx_non_pf = true; tx_non_pf = true;
} }
} }

@ -197,8 +197,9 @@ void DetectPktInspectEngineRegister(const char *name,
* *
* \note errors are fatal */ * \note errors are fatal */
static void AppLayerInspectEngineRegisterInternal(const char *name, AppProto alproto, uint32_t dir, static void AppLayerInspectEngineRegisterInternal(const char *name, AppProto alproto, uint32_t dir,
uint8_t sub_state, uint8_t progress, InspectEngineFuncPtr Callback, uint8_t sub_state, uint8_t min_progress, uint8_t max_progress,
InspectionBufferGetDataPtr GetData, InspectionSingleBufferGetDataPtr GetDataSingle, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData,
InspectionSingleBufferGetDataPtr GetDataSingle,
InspectionMultiBufferGetDataPtr GetMultiData) InspectionMultiBufferGetDataPtr GetMultiData)
{ {
/* ignore special case unknown */ /* ignore special case unknown */
@ -206,7 +207,8 @@ static void AppLayerInspectEngineRegisterInternal(const char *name, AppProto alp
DEBUG_VALIDATE_BUG_ON(AppLayerParserSupportsSubStates(alproto) && sub_state == 0); DEBUG_VALIDATE_BUG_ON(AppLayerParserSupportsSubStates(alproto) && sub_state == 0);
DEBUG_VALIDATE_BUG_ON(!AppLayerParserSupportsSubStates(alproto) && sub_state != 0); DEBUG_VALIDATE_BUG_ON(!AppLayerParserSupportsSubStates(alproto) && sub_state != 0);
} }
BUG_ON(progress >= APP_LAYER_MAX_PROGRESS); BUG_ON(max_progress >= APP_LAYER_MAX_PROGRESS);
BUG_ON(max_progress < min_progress);
DetectBufferTypeRegister(name); DetectBufferTypeRegister(name);
const int sm_list = DetectBufferTypeGetByName(name); const int sm_list = DetectBufferTypeGetByName(name);
@ -216,8 +218,8 @@ static void AppLayerInspectEngineRegisterInternal(const char *name, AppProto alp
SCLogDebug("name %s id %d", name, sm_list); SCLogDebug("name %s id %d", name, sm_list);
if ((alproto == ALPROTO_FAILED) || (!(dir == SIG_FLAG_TOSERVER || dir == SIG_FLAG_TOCLIENT)) || if ((alproto == ALPROTO_FAILED) || (!(dir == SIG_FLAG_TOSERVER || dir == SIG_FLAG_TOCLIENT)) ||
(sm_list < DETECT_SM_LIST_MATCH) || (sm_list >= SHRT_MAX) || (progress >= 48) || (sm_list < DETECT_SM_LIST_MATCH) || (sm_list >= SHRT_MAX) ||
(Callback == NULL)) { (max_progress >= APP_LAYER_MAX_PROGRESS) || (Callback == NULL)) {
SCLogError("Invalid arguments"); SCLogError("Invalid arguments");
BUG_ON(1); BUG_ON(1);
} else if (Callback == DetectEngineInspectBufferGeneric && GetData == NULL) { } else if (Callback == DetectEngineInspectBufferGeneric && GetData == NULL) {
@ -249,8 +251,9 @@ static void AppLayerInspectEngineRegisterInternal(const char *name, AppProto alp
new_engine->dir = direction; new_engine->dir = direction;
new_engine->sm_list = (uint16_t)sm_list; new_engine->sm_list = (uint16_t)sm_list;
new_engine->sm_list_base = (uint16_t)sm_list; new_engine->sm_list_base = (uint16_t)sm_list;
new_engine->progress = progress;
new_engine->sub_state = sub_state; new_engine->sub_state = sub_state;
new_engine->min_progress = min_progress;
new_engine->max_progress = max_progress;
new_engine->v2.Callback = Callback; new_engine->v2.Callback = Callback;
if (Callback == DetectEngineInspectBufferGeneric) { if (Callback == DetectEngineInspectBufferGeneric) {
new_engine->v2.GetData = GetData; new_engine->v2.GetData = GetData;
@ -272,6 +275,45 @@ static void AppLayerInspectEngineRegisterInternal(const char *name, AppProto alp
} }
} }
/**
* \brief register an app-layer inspect engine with a min and max progress
*
* \param name the buffer name
* \param alproto app-layer protocol
* \param dir direction
* \param progress1 first progress to run the engine
* \param progress2 second progress where we can run the engine
* \param Callback callback function, can be generic DetectEngineInspectBufferGeneric
* \param GetData seconday callback in case of use of DetectEngineInspectBufferGeneric
*/
void DetectAppLayerInspectEngineRegister2(const char *name, AppProto alproto, uint32_t dir,
uint8_t progress1, uint8_t progress2, InspectEngineFuncPtr Callback,
InspectionBufferGetDataPtr GetData)
{
/* before adding, check that we don't add a duplicate entry, which will
* propagate all the way into the packet runtime if allowed. */
DetectEngineAppInspectionEngine *t = g_app_inspect_engines;
if (progress1 >= progress2) {
FatalError(
"Bad order for progresses for %s : %d should be > %d", name, progress1, progress2);
}
while (t != NULL) {
const uint32_t t_direction = t->dir == 0 ? SIG_FLAG_TOSERVER : SIG_FLAG_TOCLIENT;
const int sm_list = DetectBufferTypeGetByName(name);
if (t->sm_list == sm_list && t->alproto == alproto && t_direction == dir &&
t->min_progress == progress1 && t->v2.Callback == Callback &&
t->v2.GetData == GetData) {
DEBUG_VALIDATE_BUG_ON(1);
return;
}
t = t->next;
}
AppLayerInspectEngineRegisterInternal(
name, alproto, dir, 0, progress1, progress2, Callback, GetData, NULL, NULL);
}
void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir, void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uint32_t dir,
uint8_t progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData) uint8_t progress, InspectEngineFuncPtr Callback, InspectionBufferGetDataPtr GetData)
{ {
@ -283,7 +325,7 @@ void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uin
const int sm_list = DetectBufferTypeGetByName(name); const int sm_list = DetectBufferTypeGetByName(name);
if (t->sm_list == sm_list && t->alproto == alproto && t_direction == dir && if (t->sm_list == sm_list && t->alproto == alproto && t_direction == dir &&
t->sub_state == 0 && t->progress == progress && t->v2.Callback == Callback && t->sub_state == 0 && t->min_progress == progress && t->v2.Callback == Callback &&
t->v2.GetData == GetData) { t->v2.GetData == GetData) {
DEBUG_VALIDATE_BUG_ON(1); DEBUG_VALIDATE_BUG_ON(1);
return; return;
@ -292,7 +334,7 @@ void DetectAppLayerInspectEngineRegister(const char *name, AppProto alproto, uin
} }
AppLayerInspectEngineRegisterInternal( AppLayerInspectEngineRegisterInternal(
name, alproto, dir, 0, (uint8_t)progress, Callback, GetData, NULL, NULL); name, alproto, dir, 0, progress, progress, Callback, GetData, NULL, NULL);
} }
void DetectAppLayerInspectEngineRegisterSubState(const char *name, AppProto alproto, uint32_t dir, void DetectAppLayerInspectEngineRegisterSubState(const char *name, AppProto alproto, uint32_t dir,
@ -307,7 +349,7 @@ void DetectAppLayerInspectEngineRegisterSubState(const char *name, AppProto alpr
const int sm_list = DetectBufferTypeGetByName(name); const int sm_list = DetectBufferTypeGetByName(name);
if (t->sm_list == sm_list && t->alproto == alproto && t_direction == dir && if (t->sm_list == sm_list && t->alproto == alproto && t_direction == dir &&
t->sub_state == sub_state && t->progress == progress && t->sub_state == sub_state && t->min_progress == progress &&
t->v2.Callback == Callback && t->v2.GetData == GetData) { t->v2.Callback == Callback && t->v2.GetData == GetData) {
DEBUG_VALIDATE_BUG_ON(1); DEBUG_VALIDATE_BUG_ON(1);
return; return;
@ -316,7 +358,7 @@ void DetectAppLayerInspectEngineRegisterSubState(const char *name, AppProto alpr
} }
AppLayerInspectEngineRegisterInternal( AppLayerInspectEngineRegisterInternal(
name, alproto, dir, sub_state, progress, Callback, GetData, NULL, NULL); name, alproto, dir, sub_state, progress, progress, Callback, GetData, NULL, NULL);
} }
void DetectAppLayerInspectEngineRegisterSingle(const char *name, AppProto alproto, uint32_t dir, void DetectAppLayerInspectEngineRegisterSingle(const char *name, AppProto alproto, uint32_t dir,
uint8_t progress, InspectEngineFuncPtr Callback, InspectionSingleBufferGetDataPtr GetData) uint8_t progress, InspectEngineFuncPtr Callback, InspectionSingleBufferGetDataPtr GetData)
@ -329,7 +371,7 @@ void DetectAppLayerInspectEngineRegisterSingle(const char *name, AppProto alprot
const int sm_list = DetectBufferTypeGetByName(name); const int sm_list = DetectBufferTypeGetByName(name);
if (t->sm_list == sm_list && t->alproto == alproto && t_direction == dir && if (t->sm_list == sm_list && t->alproto == alproto && t_direction == dir &&
t->progress == progress && t->v2.Callback == Callback && t->min_progress == progress && t->v2.Callback == Callback &&
t->v2.GetDataSingle == GetData) { t->v2.GetDataSingle == GetData) {
DEBUG_VALIDATE_BUG_ON(1); DEBUG_VALIDATE_BUG_ON(1);
return; return;
@ -338,7 +380,7 @@ void DetectAppLayerInspectEngineRegisterSingle(const char *name, AppProto alprot
} }
AppLayerInspectEngineRegisterInternal( AppLayerInspectEngineRegisterInternal(
name, alproto, dir, 0, (uint8_t)progress, Callback, NULL, GetData, NULL); name, alproto, dir, 0, progress, progress, Callback, NULL, GetData, NULL);
} }
/* copy an inspect engine with transforms to a new list id. */ /* copy an inspect engine with transforms to a new list id. */
@ -360,7 +402,8 @@ static void DetectAppLayerInspectEngineCopy(
new_engine->sm_list = (uint16_t)new_list; /* use new list id */ new_engine->sm_list = (uint16_t)new_list; /* use new list id */
DEBUG_VALIDATE_BUG_ON(sm_list < 0 || sm_list > UINT16_MAX); DEBUG_VALIDATE_BUG_ON(sm_list < 0 || sm_list > UINT16_MAX);
new_engine->sm_list_base = (uint16_t)sm_list; new_engine->sm_list_base = (uint16_t)sm_list;
new_engine->progress = t->progress; new_engine->min_progress = t->min_progress;
new_engine->max_progress = t->max_progress;
new_engine->sub_state = t->sub_state; new_engine->sub_state = t->sub_state;
new_engine->v2 = t->v2; new_engine->v2 = t->v2;
new_engine->v2.transforms = transforms; /* assign transforms */ new_engine->v2.transforms = transforms; /* assign transforms */
@ -394,7 +437,8 @@ static void DetectAppLayerInspectEngineCopyListToDetectCtx(DetectEngineCtx *de_c
new_engine->dir = t->dir; new_engine->dir = t->dir;
new_engine->sm_list = t->sm_list; new_engine->sm_list = t->sm_list;
new_engine->sm_list_base = t->sm_list; new_engine->sm_list_base = t->sm_list;
new_engine->progress = t->progress; new_engine->min_progress = t->min_progress;
new_engine->max_progress = t->max_progress;
new_engine->sub_state = t->sub_state; new_engine->sub_state = t->sub_state;
new_engine->v2 = t->v2; new_engine->v2 = t->v2;
@ -614,7 +658,8 @@ static void AppendStreamInspectEngine(
new_engine->sm_list_base = DETECT_SM_LIST_PMATCH; new_engine->sm_list_base = DETECT_SM_LIST_PMATCH;
new_engine->smd = stream; new_engine->smd = stream;
new_engine->v2.Callback = DetectEngineInspectStream; new_engine->v2.Callback = DetectEngineInspectStream;
new_engine->progress = 0; new_engine->min_progress = 0;
new_engine->max_progress = 0;
/* append */ /* append */
if (s->app_inspect == NULL) { if (s->app_inspect == NULL) {
@ -783,7 +828,20 @@ static void AppendAppInspectEngine(DetectEngineCtx *de_ctx,
new_engine->sm_list_base = t->sm_list_base; new_engine->sm_list_base = t->sm_list_base;
new_engine->smd = smd; new_engine->smd = smd;
new_engine->match_on_null = smd ? DetectContentInspectionMatchOnAbsentBuffer(smd) : false; new_engine->match_on_null = smd ? DetectContentInspectionMatchOnAbsentBuffer(smd) : false;
new_engine->progress = t->progress; new_engine->min_progress = t->min_progress;
new_engine->max_progress = t->max_progress;
// A firewall rule such as
// accept:flow,alert http1:<response_headers any any -> any any (http.header; content:"xyz";
// should not have max_progress response_trailers so that DetectTxCompleted returns true at
// response_body
if ((s->flags & SIG_FLAG_FW_HOOK_LTE) && s->init_data->hook.type == SIGNATURE_HOOK_TYPE_APP &&
new_engine->max_progress > s->app_progress_hook) {
new_engine->max_progress = new_engine->min_progress;
} else if (s->init_data->hook.type == SIGNATURE_HOOK_TYPE_APP &&
(s->flags & SIG_FLAG_FW_HOOK_LTE) == 0 &&
new_engine->min_progress < s->app_progress_hook) {
new_engine->min_progress = new_engine->max_progress;
}
new_engine->sub_state = t->sub_state; new_engine->sub_state = t->sub_state;
new_engine->v2 = t->v2; new_engine->v2 = t->v2;
SCLogDebug("sm_list %d new_engine->v2 %p/%p/%p", new_engine->sm_list, new_engine->v2.Callback, SCLogDebug("sm_list %d new_engine->v2 %p/%p/%p", new_engine->sm_list, new_engine->v2.Callback,
@ -801,7 +859,8 @@ static void AppendAppInspectEngine(DetectEngineCtx *de_ctx,
} }
/* prepend engine if forced or if our engine has a lower progress. */ /* prepend engine if forced or if our engine has a lower progress. */
} else if (prepend || (!(*head_is_mpm) && s->app_inspect->progress > new_engine->progress)) { } else if (prepend ||
(!(*head_is_mpm) && s->app_inspect->min_progress > new_engine->min_progress)) {
new_engine->next = s->app_inspect; new_engine->next = s->app_inspect;
s->app_inspect = new_engine; s->app_inspect = new_engine;
if (new_engine->sm_list == files_id) { if (new_engine->sm_list == files_id) {
@ -816,7 +875,7 @@ static void AppendAppInspectEngine(DetectEngineCtx *de_ctx,
} else { } else {
DetectEngineAppInspectionEngine *a = s->app_inspect; DetectEngineAppInspectionEngine *a = s->app_inspect;
while (a->next != NULL) { while (a->next != NULL) {
if (a->next && a->next->progress > new_engine->progress) { if (a->next && a->next->min_progress > new_engine->min_progress) {
break; break;
} }
a = a->next; a = a->next;
@ -966,7 +1025,8 @@ int DetectEngineAppInspectionEngine2Signature(DetectEngineCtx *de_ctx, Signature
DetectEngineAppInspectionEngine t = { DetectEngineAppInspectionEngine t = {
.alproto = s->init_data->hook.t.app.alproto, .alproto = s->init_data->hook.t.app.alproto,
.progress = state, .min_progress = state,
.max_progress = state,
.sub_state = s->init_data->hook.t.app.sub_state, .sub_state = s->init_data->hook.t.app.sub_state,
.sm_list = (uint16_t)sm_list, .sm_list = (uint16_t)sm_list,
.sm_list_base = (uint16_t)sm_list, .sm_list_base = (uint16_t)sm_list,
@ -1049,7 +1109,8 @@ int DetectEngineAppInspectionEngine2Signature(DetectEngineCtx *de_ctx, Signature
DetectEngineAppInspectionEngine t = { DetectEngineAppInspectionEngine t = {
.alproto = s->init_data->hook.t.app.alproto, .alproto = s->init_data->hook.t.app.alproto,
.progress = s->init_data->hook.t.app.app_progress, .min_progress = s->init_data->hook.t.app.app_progress,
.max_progress = s->init_data->hook.t.app.app_progress,
.sub_state = s->init_data->hook.t.app.sub_state, .sub_state = s->init_data->hook.t.app.sub_state,
.sm_list = (uint16_t)s->init_data->hook.sm_list, .sm_list = (uint16_t)s->init_data->hook.sm_list,
.sm_list_base = (uint16_t)s->init_data->hook.sm_list, .sm_list_base = (uint16_t)s->init_data->hook.sm_list,
@ -1082,9 +1143,9 @@ int DetectEngineAppInspectionEngine2Signature(DetectEngineCtx *de_ctx, Signature
#ifdef DEBUG #ifdef DEBUG
const DetectEngineAppInspectionEngine *iter = s->app_inspect; const DetectEngineAppInspectionEngine *iter = s->app_inspect;
while (iter) { while (iter) {
SCLogDebug("%u: engine %s id %u progress %d %s", s->id, SCLogDebug("%u: engine %s id %u progress %d-%d %s", s->id,
DetectEngineBufferTypeGetNameById(de_ctx, iter->sm_list), iter->id, iter->progress, DetectEngineBufferTypeGetNameById(de_ctx, iter->sm_list), iter->id,
iter->sm_list == mpm_list ? "MPM" : ""); iter->min_progress, iter->max_progress, iter->sm_list == mpm_list ? "MPM" : "");
iter = iter->next; iter = iter->next;
} }
#endif #endif
@ -2143,10 +2204,10 @@ static bool DetectTxCompleted(
if (progress < 0) { if (progress < 0) {
return false; return false;
} }
if (progress > engine->progress) { if (progress > engine->max_progress) {
return true; return true;
} }
if (progress < engine->progress) { if (progress < engine->max_progress) {
return false; return false;
} }
return progress == AppLayerParserGetTxEndState(f->proto, f->alproto, txv, flags); return progress == AppLayerParserGetTxEndState(f->proto, f->alproto, txv, flags);
@ -2318,7 +2379,7 @@ void DetectAppLayerMultiRegisterSubState(const char *name, AppProto alproto, uin
uint8_t sub_state, uint8_t progress, InspectionMultiBufferGetDataPtr GetData, int priority) uint8_t sub_state, uint8_t progress, InspectionMultiBufferGetDataPtr GetData, int priority)
{ {
BUG_ON(AppLayerParserSupportsSubStates(alproto) && sub_state == 0); BUG_ON(AppLayerParserSupportsSubStates(alproto) && sub_state == 0);
AppLayerInspectEngineRegisterInternal(name, alproto, dir, sub_state, progress, AppLayerInspectEngineRegisterInternal(name, alproto, dir, sub_state, progress, progress,
DetectEngineInspectMultiBufferGeneric, NULL, NULL, GetData); DetectEngineInspectMultiBufferGeneric, NULL, NULL, GetData);
DetectAppLayerMpmMultiRegisterSubState(name, dir, priority, PrefilterMultiGenericMpmRegister, DetectAppLayerMpmMultiRegisterSubState(name, dir, priority, PrefilterMultiGenericMpmRegister,
GetData, alproto, sub_state, progress); GetData, alproto, sub_state, progress);
@ -2330,7 +2391,7 @@ void DetectAppLayerMultiRegister(const char *name, AppProto alproto, uint32_t di
InspectionMultiBufferGetDataPtr GetData, int priority) InspectionMultiBufferGetDataPtr GetData, int priority)
{ {
BUG_ON(AppLayerParserSupportsSubStates(alproto)); BUG_ON(AppLayerParserSupportsSubStates(alproto));
AppLayerInspectEngineRegisterInternal(name, alproto, dir, 0, (uint8_t)progress, AppLayerInspectEngineRegisterInternal(name, alproto, dir, 0, progress, progress,
DetectEngineInspectMultiBufferGeneric, NULL, NULL, GetData); DetectEngineInspectMultiBufferGeneric, NULL, NULL, GetData);
DetectAppLayerMpmMultiRegister( DetectAppLayerMpmMultiRegister(
name, dir, priority, PrefilterMultiGenericMpmRegister, GetData, alproto, progress); name, dir, priority, PrefilterMultiGenericMpmRegister, GetData, alproto, progress);

@ -172,6 +172,10 @@ void DetectAppLayerInspectEngineRegisterSubState(const char *name, AppProto alpr
uint8_t type, uint8_t progress, InspectEngineFuncPtr Callback2, uint8_t type, uint8_t progress, InspectEngineFuncPtr Callback2,
InspectionBufferGetDataPtr GetData); InspectionBufferGetDataPtr GetData);
void DetectAppLayerInspectEngineRegister2(const char *name, AppProto alproto, uint32_t dir,
uint8_t progress1, uint8_t progress2, InspectEngineFuncPtr Callback2,
InspectionBufferGetDataPtr GetData);
void DetectAppLayerInspectEngineRegisterSingle(const char *name, AppProto alproto, uint32_t dir, void DetectAppLayerInspectEngineRegisterSingle(const char *name, AppProto alproto, uint32_t dir,
uint8_t progress, InspectEngineFuncPtr Callback2, InspectionSingleBufferGetDataPtr GetData); uint8_t progress, InspectEngineFuncPtr Callback2, InspectionSingleBufferGetDataPtr GetData);

@ -493,8 +493,8 @@ uint8_t DetectEngineInspectFiledata(DetectEngineCtx *de_ctx, DetectEngineThreadC
if (ffc == NULL) { if (ffc == NULL) {
return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILES; return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILES;
} }
const bool eof = const bool eof = (AppLayerParserGetStateProgress(f->proto, f->alproto, txv, flags) >
(AppLayerParserGetStateProgress(f->proto, f->alproto, txv, flags) > engine->progress); engine->max_progress);
if (ffc->head == NULL) { if (ffc->head == NULL) {
if (eof && engine->match_on_null) { if (eof && engine->match_on_null) {
return DETECT_ENGINE_INSPECT_SIG_MATCH; return DETECT_ENGINE_INSPECT_SIG_MATCH;

@ -310,7 +310,7 @@ static uint8_t DetectEngineInspectFilemagic(DetectEngineCtx *de_ctx, DetectEngin
FileContainer *ffc = files.fc; FileContainer *ffc = files.fc;
if (ffc == NULL || ffc->head == NULL) { if (ffc == NULL || ffc->head == NULL) {
const bool eof = (AppLayerParserGetStateProgress(f->proto, f->alproto, txv, flags) > const bool eof = (AppLayerParserGetStateProgress(f->proto, f->alproto, txv, flags) >
engine->progress); engine->max_progress);
if (eof && engine->match_on_null) { if (eof && engine->match_on_null) {
return DETECT_ENGINE_INSPECT_SIG_MATCH; return DETECT_ENGINE_INSPECT_SIG_MATCH;
} }

@ -245,7 +245,7 @@ static uint8_t DetectEngineInspectFilename(DetectEngineCtx *de_ctx, DetectEngine
FileContainer *ffc = files.fc; FileContainer *ffc = files.fc;
if (ffc == NULL || ffc->head == NULL) { if (ffc == NULL || ffc->head == NULL) {
const bool eof = (AppLayerParserGetStateProgress(f->proto, f->alproto, txv, flags) > const bool eof = (AppLayerParserGetStateProgress(f->proto, f->alproto, txv, flags) >
engine->progress); engine->max_progress);
if (eof && engine->match_on_null) { if (eof && engine->match_on_null) {
return DETECT_ENGINE_INSPECT_SIG_MATCH; return DETECT_ENGINE_INSPECT_SIG_MATCH;
} }

@ -311,8 +311,8 @@ static uint8_t DetectEngineInspectBufferHttpBody(DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, const DetectEngineAppInspectionEngine *engine, DetectEngineThreadCtx *det_ctx, const DetectEngineAppInspectionEngine *engine,
const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id) const Signature *s, Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
{ {
bool eof = bool eof = (AppLayerParserGetStateProgress(f->proto, f->alproto, txv, flags) >
(AppLayerParserGetStateProgress(f->proto, f->alproto, txv, flags) > engine->progress); engine->max_progress);
const InspectionBuffer *buffer = HttpRequestBodyGetDataCallback( const InspectionBuffer *buffer = HttpRequestBodyGetDataCallback(
det_ctx, engine->v2.transforms, f, flags, txv, engine->sm_list, engine->sm_list_base); det_ctx, engine->v2.transforms, f, flags, txv, engine->sm_list, engine->sm_list_base);
if (buffer == NULL || buffer->inspect == NULL) { if (buffer == NULL || buffer->inspect == NULL) {

@ -386,14 +386,16 @@ void DetectHttpHeaderRegister(void)
sigmatch_table[DETECT_HTTP_HEADER].flags |= SIGMATCH_NOOPT; sigmatch_table[DETECT_HTTP_HEADER].flags |= SIGMATCH_NOOPT;
sigmatch_table[DETECT_HTTP_HEADER].flags |= SIGMATCH_INFO_STICKY_BUFFER; sigmatch_table[DETECT_HTTP_HEADER].flags |= SIGMATCH_INFO_STICKY_BUFFER;
DetectAppLayerInspectEngineRegister("http_header", ALPROTO_HTTP1, SIG_FLAG_TOSERVER, DetectAppLayerInspectEngineRegister2("http_header", ALPROTO_HTTP1, SIG_FLAG_TOSERVER,
HTP_REQUEST_PROGRESS_HEADERS, DetectEngineInspectBufferGeneric, GetData1); HTP_REQUEST_PROGRESS_HEADERS, HTP_REQUEST_PROGRESS_TRAILER,
DetectEngineInspectBufferGeneric, GetData1);
DetectAppLayerMpmRegister("http_header", SIG_FLAG_TOSERVER, 2, DetectAppLayerMpmRegister("http_header", SIG_FLAG_TOSERVER, 2,
PrefilterMpmHttpHeaderRequestRegister, NULL, ALPROTO_HTTP1, PrefilterMpmHttpHeaderRequestRegister, NULL, ALPROTO_HTTP1,
0); /* not used, registered twice: HEADERS/TRAILER */ 0); /* not used, registered twice: HEADERS/TRAILER */
DetectAppLayerInspectEngineRegister("http_header", ALPROTO_HTTP1, SIG_FLAG_TOCLIENT, DetectAppLayerInspectEngineRegister2("http_header", ALPROTO_HTTP1, SIG_FLAG_TOCLIENT,
HTP_RESPONSE_PROGRESS_HEADERS, DetectEngineInspectBufferGeneric, GetData1); HTP_RESPONSE_PROGRESS_HEADERS, HTP_RESPONSE_PROGRESS_TRAILER,
DetectEngineInspectBufferGeneric, GetData1);
DetectAppLayerMpmRegister("http_header", SIG_FLAG_TOCLIENT, 2, DetectAppLayerMpmRegister("http_header", SIG_FLAG_TOCLIENT, 2,
PrefilterMpmHttpHeaderResponseRegister, NULL, ALPROTO_HTTP1, PrefilterMpmHttpHeaderResponseRegister, NULL, ALPROTO_HTTP1,
0); /* not used, registered twice: HEADERS/TRAILER */ 0); /* not used, registered twice: HEADERS/TRAILER */

@ -3084,17 +3084,14 @@ static int SigValidateCheckBuffers(
} }
if (s->init_data->hook.type == SIGNATURE_HOOK_TYPE_APP) { if (s->init_data->hook.type == SIGNATURE_HOOK_TYPE_APP) {
if ((s->flags & SIG_FLAG_TOSERVER) && (app->dir == 0) && bool samedir = ((s->flags & SIG_FLAG_TOSERVER) && (app->dir == 0)) ||
app->progress != s->init_data->hook.t.app.app_progress) { ((s->flags & SIG_FLAG_TOCLIENT) && (app->dir == 1));
SCLogError("engine progress value %d doesn't match hook %u", app->progress, if (samedir && app->min_progress != s->init_data->hook.t.app.app_progress &&
app->max_progress != s->init_data->hook.t.app.app_progress) {
SCLogError("engine progress value %d doesn't match hook %u", app->min_progress,
s->init_data->hook.t.app.app_progress); s->init_data->hook.t.app.app_progress);
SCReturnInt(0); SCReturnInt(0);
} }
if ((s->flags & SIG_FLAG_TOCLIENT) && (app->dir == 1) &&
app->progress != s->init_data->hook.t.app.app_progress) {
SCLogError("engine progress value doesn't match hook");
SCReturnInt(0);
}
} }
buffer_consumed = true; buffer_consumed = true;

@ -1370,14 +1370,14 @@ static int DetectRunTxInspectRule(ThreadVars *tv, DetectEngineCtx *de_ctx,
"skip because engine alproto %s sub_state %u != tx_type %u (engine " "skip because engine alproto %s sub_state %u != tx_type %u (engine "
"progress %u)", "progress %u)",
AppProtoToString(engine->alproto), engine->sub_state, tx->tx_type, AppProtoToString(engine->alproto), engine->sub_state, tx->tx_type,
engine->progress); engine->min_progress);
engine = engine->next; engine = engine->next;
continue; continue;
} }
TRACE_SID_TXS(s->id, tx, TRACE_SID_TXS(s->id, tx,
"inspecting engine alproto %s sub_state %u == tx_type %u (engine progress %u)", "inspecting engine alproto %s sub_state %u == tx_type %u (engine progress %u)",
AppProtoToString(engine->alproto), engine->sub_state, tx->tx_type, AppProtoToString(engine->alproto), engine->sub_state, tx->tx_type,
engine->progress); engine->min_progress);
void *tx_ptr = DetectGetInnerTx(tx->tx_ptr, f->alproto, engine->alproto, flow_flags); void *tx_ptr = DetectGetInnerTx(tx->tx_ptr, f->alproto, engine->alproto, flow_flags);
if (tx_ptr == NULL) { if (tx_ptr == NULL) {
@ -1396,23 +1396,33 @@ static int DetectRunTxInspectRule(ThreadVars *tv, DetectEngineCtx *de_ctx,
/* engines are sorted per progress, except that the one with /* engines are sorted per progress, except that the one with
* mpm/prefilter enabled is first */ * mpm/prefilter enabled is first */
if (tx->tx_progress < engine->progress) { if (tx->tx_progress < engine->min_progress) {
SCLogDebug("tx progress %d < engine progress %d", SCLogDebug("tx progress %d < engine progress %d", tx->tx_progress,
tx->tx_progress, engine->progress); engine->min_progress);
break; break;
} }
if (engine->mpm) { if (engine->mpm) {
if (tx->tx_progress > engine->progress) { if (tx->tx_progress > engine->max_progress) {
TRACE_SID_TXS(s->id, tx, TRACE_SID_TXS(s->id, tx,
"engine->mpm: t->tx_progress %u > engine->progress %u, so set " "engine->mpm: t->tx_progress %u > engine->max_progress %u, so set "
"mpm_before_progress", "mpm_before_progress",
tx->tx_progress, engine->progress); tx->tx_progress, engine->max_progress);
mpm_before_progress = true; mpm_before_progress = true;
} else if (tx->tx_progress == engine->progress) { } else if (tx->tx_progress == engine->min_progress) {
// do not use >= min progress && <= max_progress here
// because mpm_in_progress is used to optimize and
// not store partially (so far) matching signature as next
// packet with next progress will re-run mpm.
// But for a rule with
// a http1 header as fast_pattern/mpm
// a http1 method, and some content on client body
// when we are in body progress and do not match yet the content
// we will not re-run http_header prefilter for headers progress
// so we need to store signature
TRACE_SID_TXS(s->id, tx, TRACE_SID_TXS(s->id, tx,
"engine->mpm: t->tx_progress %u == engine->progress %u, so set " "engine->mpm: t->tx_progress %u == engine->min_progress %u, so set "
"mpm_in_progress", "mpm_in_progress",
tx->tx_progress, engine->progress); tx->tx_progress, engine->min_progress);
if ((p->flags & PKT_PSEUDO_DETECTLOG_FLUSH) == 0) { if ((p->flags & PKT_PSEUDO_DETECTLOG_FLUSH) == 0) {
mpm_in_progress = true; mpm_in_progress = true;
} }
@ -1431,13 +1441,14 @@ static int DetectRunTxInspectRule(ThreadVars *tv, DetectEngineCtx *de_ctx,
} else if (engine->v2.Callback == NULL) { } else if (engine->v2.Callback == NULL) {
/* TODO is this the cleanest way to support a non-app sig on a app hook? */ /* TODO is this the cleanest way to support a non-app sig on a app hook? */
if (tx->tx_progress > engine->progress) { if (tx->tx_progress > engine->max_progress) {
mpm_before_progress = true; // TODO needs a new name now mpm_before_progress = true; // TODO needs a new name now
} }
/* we don't have to store a "hook" match, also don't want to keep any state to make /* we don't have to store a "hook" match, also don't want to keep any state to make
* sure the hook gets invoked again until tx progress progresses. */ * sure the hook gets invoked again until tx progress progresses. */
if ((s->flags & SIG_FLAG_FW_HOOK_LTE) == 0 && tx->tx_progress <= engine->progress) { if ((s->flags & SIG_FLAG_FW_HOOK_LTE) == 0 &&
tx->tx_progress <= engine->max_progress) {
return 1; // DETECT_ENGINE_INSPECT_SIG_MATCH; return 1; // DETECT_ENGINE_INSPECT_SIG_MATCH;
} }

@ -427,8 +427,13 @@ typedef struct DetectEngineAppInspectionEngine_ {
bool match_on_null; bool match_on_null;
uint16_t sm_list; uint16_t sm_list;
uint16_t sm_list_base; /**< base buffer being transformed */ uint16_t sm_list_base; /**< base buffer being transformed */
uint8_t progress;
uint8_t sub_state; /**< matches tx type */ uint8_t sub_state; /**< matches tx type */
// An app-layer inspection engine may run at different progresses.
// Even if most engines run at only one progress (min_progress=max_progress)
// http_header keyword may run for headers and trailers progress for example
uint8_t min_progress;
// max_progress allows us to not give up on matching too soon
uint8_t max_progress;
struct { struct {
union { union {

Loading…
Cancel
Save