Skip to content

Commit

Permalink
requires: add option to ignore unknown requirements
Browse files Browse the repository at this point in the history
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: OISF#7434
  • Loading branch information
jasonish committed Dec 4, 2024
1 parent e048adb commit 69c9d44
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 7 deletions.
19 changes: 17 additions & 2 deletions doc/userguide/upgrade.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
--------------------
Expand Down
11 changes: 7 additions & 4 deletions rust/src/detect/requires.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(","),
));
Expand Down Expand Up @@ -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)) {
Expand All @@ -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 {
Expand All @@ -497,6 +499,7 @@ pub unsafe extern "C" fn SCDetectCheckRequires(
RequiresError::VersionGt => {
status.gt_count += 1;
}
RequiresError::UnknownRequirement(_) => {}
_ => {}
}
*errstr = err.c_errmsg();
Expand Down
8 changes: 7 additions & 1 deletion src/detect-requires.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
Expand All @@ -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";
Expand Down

0 comments on commit 69c9d44

Please sign in to comment.