Project

General

Profile

Actions

Feature #9363

open
JI JI

Task #7499: tracking: rust/plugins: first class support for rust plugins

detect/plugins: expose keyword setup accessors to plugins and Rust

Feature #9363: detect/plugins: expose keyword setup accessors to plugins and Rust

Added by Jason Ish about 10 hours ago. Updated about 9 hours ago.

Status:
In Review
Priority:
Normal
Assignee:
Target version:
Effort:
Difficulty:
Label:

Description

Keywords implemented in plugins or in Rust can't access the Signature, SigMatch and sigmatch_table internals that built-in keywords use when they are registered and when their rule options are set up, because those types are opaque to them and their layout changes with build options (for example --enable-profiling-rules). Three common things such a keyword needs are therefore impossible without calling unexported functions or mirroring struct offsets:

  1. Packet match callback: SCDetectHelperKeywordRegister() takes an SCSigTableAppLiteElmt, which only has an app-layer transaction match callback. A packet keyword has to write its Match callback into sigmatch_table directly.
  2. Negation: keywords registered with SIGMATCH_HANDLE_NEGATION get the leading ! stripped by the rule parser, which records it in Signature::init_data. The flag is already exposed to Rust, but there is no way to read the result.
  3. Earlier instances of the same keyword: keywords like app-layer-protocol and ipproto walk the signature's packet match list to reject duplicate or conflicting options, reading each earlier instance's context. SCDetectGetLastSMFromLists() is not a substitute: it only returns the last match, gives no access to its context, and ignores the packet match list once a sticky buffer is active in the rule.

Proposal

Add functions to the detect API, exposed through the generated Rust bindings:

  • SCDetectHelperKeywordPacketMatchRegister(kwid, Match): install a packet match callback for a keyword registered with SCDetectHelperKeywordRegister(), without changing the SCSigTableAppLiteElmt layout
  • SCDetectSignatureIsNegated(s): whether the option being set up was negated
  • SCDetectSignatureGetLastSMByType(s, list_id, type): last SigMatch of a keyword in one of the static lists (e.g. DETECT_SM_LIST_MATCH)
  • SCSigMatchGetPrevByType(sm, type): previous SigMatch of the same keyword
  • SCSigMatchGetCtx(sm): the keyword context of a SigMatch

The lookup is limited to the static lists from DetectSigmatchListEnum. That enum is moved to detect-engine-register.h and allowlisted in the Rust bindings, so Rust keywords can use DETECT_SM_LIST_MATCH instead of hardcoding it.

Users

  • The in-tree nDPI plugin is converted to register its ndpi-protocol and ndpi-risk keywords through the helpers, and to use the accessors for their negation and conflict checks, so it no longer touches sigmatch_table, Signature or SigMatch internals.
  • An external nDPI plugin written in Rust uses them in place of writing into sigmatch_table through a probed struct layout, calling the unexported DetectGetLastSMByListId(), and walking SigMatch through mirrored struct offsets.
  • The flowbits and ipproto keywords use the SigMatch lookup as in-tree examples, and unit tests in src/tests/util-plugin.c cover the patterns from a keyword registered the way a plugin does it.

Related

  • #7499 tracking: rust/plugins: first class support for rust plugins
  • #8632 plugins(ndpi): add flow accessors for opaque usage of flow

JI Updated by Jason Ish about 9 hours ago Actions #1

  • Description updated (diff)

JI Updated by Jason Ish about 9 hours ago Actions #2

  • Status changed from In Progress to In Review
Actions

Also available in: PDF Atom