Suricata 8.0 dynamic alproto can not be disabled

Outputing:
[35686] Notice: suricata: This is znsm version 8.0.0 RELEASE running in SYSTEM mode
[35686] Info: cpu: CPUs/cores online: 16
[35686] Info: dpdk: Setting IPS mode
[35686] Warning: runmodes: disabling livedev.use-for-tracking with IPS mode. See ticket #6726.
[35686] Info: exception-policy: master exception-policy set to: auto
[35686] Info: app-layer-ftp: Parser disabled for ftp protocol. Protocol detection still on.
[35686] Info: app-layer-smtp: Parser disabled for smtp protocol. Protocol detection still on.
ERROR: incomplete app-layer registration
AppLayer protocol snmp ipproto 6

  • option flags 214
  • first_data_dir db
    Mandatory:
  • Parser[0] (nil) Parser[1] 0x3f1
  • StateAlloc 0x380 StateFree 0x38000
  • StateGetTx (nil) StateGetTxCnt (nil) StateTransactionFree 0xa9172f1d
  • GetTxData (nil)
  • GetStateData (nil)
  • StateGetProgress 0x100000000
    Optional:
  • LocalStorageAlloc 0x3000000000 LocalStorageFree (nil)
  • StateGetEventInfo 0x2000000000 StateGetEventInfoById 0x20

Problem:
When snmp is disabled, suricata 8.0 exits dule to func call chain“ValidateParsers→ValidateParser→ValidateParserProto”.

Reason:
Source code shows that though a dynamic alproto’s AppProtoEnum is asigned(which lead to increament of variable g_alproto_max) by AppProtoNewProtoFromString, alp_ctx.ctxs won’t be reallocated until func call chain“AppLayerRegisterParser→AppLayerParserRegisterStateFuncs“ which implies that the dynamic alproto is enabled. The func “ValidateParsers“ validates all g_alproto_max ctxs, access ctx[g_alproto_max-1] which is not reallocated.

Solution:
I found that to modify validator(like ValidateParsers) is not a good idea, beacause other code will access ctx[g_alproto_max-1]. So I add a func named AppLayerParserReallocCtx in app-layer-parser.c, add called in func AppProtoRegisterProtoString.

New Function:
int AppLayerParserReallocCtx(AppProto alproto)
{
if (alp_ctx.ctxs_len <= alproto) {
// Realloc alp_ctx.ctxs, so that dynamic alproto can be treated as real/normal ones.
// In case we need to turn off dynamic alproto.
void *tmp = SCRealloc(alp_ctx.ctxs,
sizeof(AppLayerParserProtoCtx[FLOW_PROTO_MAX]) * (alp_ctx.ctxs_len + ARRAY_CAP_STEP));
if (unlikely(tmp == NULL)) {
FatalError(“Unable to realloc alp_ctx.ctxs.”);
}
alp_ctx.ctxs = tmp;
memset(&alp_ctx.ctxs[alp_ctx.ctxs_len], 0, sizeof(AppLayerParserProtoCtx[FLOW_PROTO_MAX]) * ARRAY_CAP_STEP);
alp_ctx.ctxs_len += ARRAY_CAP_STEP;
}

return 0;

}

Hi! SNMP was particularly broken and was fixed in the latest point release `8.0.1`. See the tracking ticket: Bug #7820: app-layer/snmp: internal error if app-layer is disabled - Suricata - Open Information Security Foundation

If you see this for any other protocol as well, please feel free to report.

We happily accept code contributions for any betterment but that should come via GitHub. GitHub - OISF/suricata: Suricata is a network Intrusion Detection System, Intrusion Prevention System and Network Security Monitoring engine developed by the OISF and the Suricata community.

I just had tested the fix. When snmp app-layer configuration is “enabled: no“, the problem is resulved. but when “enabled: detection-only“, The problem still exists. Beacause ctxs is not reallocaged when the configuration is “enabled: detection-only“.

Indeed. I can confirm detection-only is buggy. Could you please create a ticket for this on our Redmine? https://redmine.openinfosecfoundation.org

Patches are welcome on Github!

I had just create a ticket, Bug #8000: suricata 8.0 dynamic alproto can not be disabled