From 69c9d44f9a482c2022abdb05e8c36e0568017040 Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Wed, 4 Dec 2024 11:28:17 -0600 Subject: [PATCH] requires: add option to ignore unknown requirements The new behavior in 8, and backported is to treat unknown requirements as unsatisfied requirements. For 7.0.8, add a configuration option, "ignore-unknown-requirements" to completely ignore unknown requirements, effectively treating them as available. Ticket: #7434 --- doc/userguide/upgrade.rst | 19 +++++++++++++++++-- rust/src/detect/requires.rs | 11 +++++++---- src/detect-requires.c | 8 +++++++- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/doc/userguide/upgrade.rst b/doc/userguide/upgrade.rst index cea1d2ee0f55..6b7f4ab24d78 100644 --- a/doc/userguide/upgrade.rst +++ b/doc/userguide/upgrade.rst @@ -37,8 +37,23 @@ dedicated new configuration. Upgrading to 7.0.7 ------------------ - Unknown requirements in the ``requires`` keyword will now be treated - as unmet requirements, causing the rule to not be loaded. See - :ref:`keyword_requires`. + as unsatisfied requirements, causing the rule to not be loaded. See + :ref:`keyword_requires`. To opt out of this change and to ignore + uknown requirements, effectively treating them as satified the + ``ignore-unknown-requirements`` configuration option can be used. + + Command line example:: + + --set ignore-unknown-requirements=true + + Or as a top-level configuration option in ``suricata.yaml``: + + .. code-block:: yaml + + default-rule-path: /var/lib/suricata/rules + rule-files: + - suricata.rules + ignore-unknown-requirements: true Upgrading 6.0 to 7.0 -------------------- diff --git a/rust/src/detect/requires.rs b/rust/src/detect/requires.rs index 2635605d265d..21cfab30ae3f 100644 --- a/rust/src/detect/requires.rs +++ b/rust/src/detect/requires.rs @@ -297,9 +297,9 @@ fn check_version( } fn check_requires( - requires: &Requires, suricata_version: &SuricataVersion, + requires: &Requires, suricata_version: &SuricataVersion, ignore_unknown: bool, ) -> Result<(), RequiresError> { - if !requires.unknown.is_empty() { + if !ignore_unknown && !requires.unknown.is_empty() { return Err(RequiresError::UnknownRequirement( requires.unknown.join(","), )); @@ -453,7 +453,7 @@ pub unsafe extern "C" fn SCDetectRequiresStatusLog( #[no_mangle] pub unsafe extern "C" fn SCDetectCheckRequires( requires: *const c_char, suricata_version_string: *const c_char, errstr: *mut *const c_char, - status: &mut SCDetectRequiresStatus, + status: &mut SCDetectRequiresStatus, ignore_unknown: c_int, ) -> c_int { // First parse the running Suricata version. let suricata_version = match parse_suricata_version(CStr::from_ptr(suricata_version_string)) { @@ -476,7 +476,9 @@ pub unsafe extern "C" fn SCDetectCheckRequires( } }; - match check_requires(&requires, &suricata_version) { + let ignore_unknown = if ignore_unknown == 0 { false } else { true }; + + match check_requires(&requires, &suricata_version, ignore_unknown) { Ok(()) => 0, Err(err) => { match &err { @@ -497,6 +499,7 @@ pub unsafe extern "C" fn SCDetectCheckRequires( RequiresError::VersionGt => { status.gt_count += 1; } + RequiresError::UnknownRequirement(_) => {} _ => {} } *errstr = err.c_errmsg(); diff --git a/src/detect-requires.c b/src/detect-requires.c index 4d7f916b3b82..78df5b41679b 100644 --- a/src/detect-requires.c +++ b/src/detect-requires.c @@ -20,6 +20,10 @@ #include "detect-engine.h" #include "rust.h" +/* Set to true if unknown requirements should be ingored. In Suricata + * 8, unknown requirements are treated as unsatisfied requirements. */ +static int g_ignore_unknown_requirements = 0; + static int DetectRequiresSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr) { if (de_ctx->requirements == NULL) { @@ -28,7 +32,7 @@ static int DetectRequiresSetup(DetectEngineCtx *de_ctx, Signature *s, const char } const char *errmsg = NULL; - int res = SCDetectCheckRequires(rawstr, PROG_VER, &errmsg, de_ctx->requirements); + int res = SCDetectCheckRequires(rawstr, PROG_VER, &errmsg, de_ctx->requirements, g_ignore_unknown_requirements); if (res == -1) { // The requires expression is bad, log an error. SCLogError("%s: %s", errmsg, rawstr); @@ -43,6 +47,8 @@ static int DetectRequiresSetup(DetectEngineCtx *de_ctx, Signature *s, const char void DetectRequiresRegister(void) { + ConfGetBool("ignore-unknown-requirements", &g_ignore_unknown_requirements); + sigmatch_table[DETECT_REQUIRES].name = "requires"; sigmatch_table[DETECT_REQUIRES].desc = "require Suricata version or features"; sigmatch_table[DETECT_REQUIRES].url = "/rules/meta-keywords.html#requires";