Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e015217
rust: format detect files
catenacyber Jun 11, 2026
a9e1dff
conf: introduce SCConfGetNonNull
catenacyber Jun 12, 2026
6bb271c
conf: uses SCConfGetNonNull
catenacyber Jun 12, 2026
df35324
detect: fail thread init on keyword ctx error
ssam18 Jun 12, 2026
565e138
pcap-file: skip setvbuf on non-seekable streams
ssam18 Jun 12, 2026
c6014a7
websocket: accepts config value with units
catenacyber Jun 12, 2026
188376b
output/filestore: refactor file descriptor handling
victorjulien Jun 2, 2026
a5effad
frames: avoid possible undefined behavior
victorjulien Jun 3, 2026
6e1f96f
tm/queues: assist gcc -fanalyzer
victorjulien Jun 3, 2026
3241457
conf: assist gcc -fanalyzer
victorjulien Jun 3, 2026
caa9dda
decode/tcp: only set data ptr for valid option lengths
victorjulien Jun 3, 2026
05eac97
detect/sigorder: handle allocation failure
victorjulien Jun 3, 2026
ff7fae5
detect/flowvar: help gcc -fanalyzer
victorjulien Jun 3, 2026
65f1a02
detect/ip_proto: clean up parsing function
victorjulien Jun 3, 2026
e2f9211
log-pcap: address gcc analyzer warnings
victorjulien Jun 4, 2026
f9cf9c1
output: suppress gcc analyzer warnings
victorjulien Jun 4, 2026
5179af5
affinity: gcc analyzer warnings
victorjulien Jun 4, 2026
32fc437
spm/bm: match suff array to pattern size
victorjulien Jun 4, 2026
f434732
util/var-name: help gcc analyzer
victorjulien Jun 4, 2026
79ef58b
mpm/hs: remove useless pointer check
victorjulien Jun 4, 2026
7cb64cc
nfq: suppress gcc analyzer warnings
victorjulien Jun 4, 2026
1eff94f
github-ci: add gcc analyzer build
victorjulien Jun 4, 2026
28b10fb
util/log: rotate log file periodically
Apr 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .github/workflows/scan-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,63 @@ jobs:
name: scan-build-results
path: scan-build-report/
retention-days: 5
gcc-analyzer:
name: GCC analyzer
runs-on: ubuntu-latest
container: ubuntu:26.04
steps:
- name: Cache scan-build
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb
with:
path: ~/.cargo
key: scan-build

- name: Install system packages
run: |
apt update
apt -y install \
libpcre2-dev \
build-essential \
autoconf \
automake \
cargo \
cbindgen \
dpdk-dev \
gcc-16 \
git \
libtool \
libpcap-dev \
libnet1-dev \
libyaml-0-2 \
libyaml-dev \
libcap-ng-dev \
libcap-ng0 \
libmagic-dev \
libnetfilter-log-dev \
libnetfilter-queue-dev \
libnetfilter-queue1 \
libnfnetlink-dev \
libnfnetlink0 \
libnuma-dev \
libhiredis-dev \
libhyperscan-dev \
libjansson-dev \
libevent-dev \
libevent-pthreads-2.1-7 \
liblz4-dev \
make \
python3-yaml \
rustc \
software-properties-common \
zlib1g \
zlib1g-dev
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- run: git config --global --add safe.directory /__w/suricata/suricata
- run: ./scripts/bundle.sh
- run: ./autogen.sh
- run: ./configure --enable-warnings --enable-dpdk --enable-nfqueue --enable-nflog --enable-debug-validation
env:
CC: gcc-16
CFLAGS: "-fanalyzer -Werror"
SURICATA_LUA_SYS_CFLAGS: ""
- run: make
4 changes: 4 additions & 0 deletions doc/userguide/capture-hardware/pcap-file.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ This can improve performance, especially for large files.
The size can be specified through the command line option, see
:ref:`--pcap-file-buffer-size <cmdline-option-pcap-file-buffer-size>`

Setting ``buffer-size`` to ``0`` disables ``setvbuf`` buffering. This is the
explicit opt-out for non-seekable sources such as ``/dev/stdin`` or named
pipes, where buffering the underlying file descriptor is not supported.

Directory-related options
-------------------------

Expand Down
3 changes: 2 additions & 1 deletion doc/userguide/partials/options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@
.. option:: --pcap-file-buffer-size <value>

Set read buffer size using ``setvbuf`` to speed up pcap reading. Valid values
are 4 KiB to 64 MiB. Default value is 128 KiB. Supported on Linux only.
are 0, which disables ``setvbuf`` buffering, or 4 KiB to 64 MiB. Default
value is 128 KiB. Supported on Linux only.

.. option:: -i <interface>

Expand Down
8 changes: 4 additions & 4 deletions plugins/pfring/runmode-pfring.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ static void *OldParsePfringConfig(const char *iface)
SCLogInfo("%s: ZC interface detected, not setting cluster-id", pfconf->iface);
} else if ((pfconf->threads == 1) && (strncmp(pfconf->iface, "dna", 3) == 0)) {
SCLogInfo("DNA interface detected, not setting cluster-id");
} else if (SCConfGet("pfring.cluster-id", &tmpclusterid) != 1) {
} else if (SCConfGetNonNull("pfring.cluster-id", &tmpclusterid) != 1) {
SCLogError("Could not get cluster-id from config");
} else {
if (StringParseInt32(&pfconf->cluster_id, 10, 0, (const char *)tmpclusterid) < 0) {
Expand All @@ -152,7 +152,7 @@ static void *OldParsePfringConfig(const char *iface)
} else if ((pfconf->threads == 1) && (strncmp(pfconf->iface, "dna", 3) == 0)) {
SCLogInfo(
"%s: DNA interface detected, not setting cluster type for PF_RING", pfconf->iface);
} else if (SCConfGet("pfring.cluster-type", &tmpctype) != 1) {
} else if (SCConfGetNonNull("pfring.cluster-type", &tmpctype) != 1) {
SCLogError("Could not get cluster-type from config");
} else if (strcmp(tmpctype, "cluster_round_robin") == 0) {
SCLogInfo("%s: Using round-robin cluster mode for PF_RING", pfconf->iface);
Expand Down Expand Up @@ -275,7 +275,7 @@ static void *ParsePfringConfig(const char *iface)
(void)SC_ATOMIC_ADD(pfconf->ref, pfconf->threads);

/* command line value has precedence */
if (SCConfGet("pfring.cluster-id", &tmpclusterid) == 1) {
if (SCConfGetNonNull("pfring.cluster-id", &tmpclusterid) == 1) {
if (StringParseInt32(&pfconf->cluster_id, 10, 0, (const char *)tmpclusterid) < 0) {
SCLogWarning("Invalid value for "
"pfring.cluster-id: '%s'. Resetting to 1.",
Expand Down Expand Up @@ -425,7 +425,7 @@ static int GetDevAndParser(const char **live_dev, ConfigIfaceParserFunc *parser)
*parser = OldParsePfringConfig;
/* In v1: try to get interface name from config */
if (*live_dev == NULL) {
if (SCConfGet("pfring.interface", live_dev) == 1) {
if (SCConfGetNonNull("pfring.interface", live_dev) == 1) {
SCLogInfo("Using interface %s", *live_dev);
LiveRegisterDevice(*live_dev);
} else {
Expand Down
3 changes: 2 additions & 1 deletion rust/src/detect/byte_extract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ fn parse_byteextract(input: &str) -> IResult<&str, SCDetectByteExtractData, Rule
let (_, values) = nom8::multi::separated_list1(
tag(","),
preceded(multispace0, nom8::bytes::complete::is_not(",")),
).parse(input)?;
)
.parse(input)?;

if values.len() < DETECT_BYTE_EXTRACT_FIXED_PARAM_COUNT
|| values.len() > DETECT_BYTE_EXTRACT_MAX_PARAM_COUNT
Expand Down
5 changes: 3 additions & 2 deletions rust/src/detect/byte_math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ fn parse_bytemath(input: &str) -> IResult<&str, DetectByteMathData, RuleParseErr
let (_, values) = nom8::multi::separated_list1(
tag(","),
preceded(multispace0, nom8::bytes::complete::is_not(",")),
).parse(input)?;
)
.parse(input)?;

if values.len() < DETECT_BYTEMATH_FIXED_PARAM_COUNT
|| values.len() > DETECT_BYTEMATH_MAX_PARAM_COUNT
Expand Down Expand Up @@ -350,7 +351,7 @@ fn parse_bytemath(input: &str) -> IResult<&str, DetectByteMathData, RuleParseErr
// Using left/right shift further restricts the value of nbytes. Note that
// validation has already ensured nbytes is in [1..10]
match byte_math.oper {
ByteMathOperator::LeftShift | ByteMathOperator::RightShift if byte_math.nbytes > 4 => {
ByteMathOperator::LeftShift | ByteMathOperator::RightShift if byte_math.nbytes > 4 => {
return Err(make_error(format!("nbytes must be 1 through 4 (inclusive) when used with \"<<\" or \">>\"; {} is not valid", byte_math.nbytes)));
}
_ => {}
Expand Down
8 changes: 4 additions & 4 deletions rust/src/detect/entropy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use nom8::sequence::preceded;
use nom8::{Err, IResult, Parser};

use std::ffi::CStr;
use std::os::raw::{c_double, c_char, c_void};
use std::os::raw::{c_char, c_double, c_void};
use std::slice;

#[repr(C)]
Expand Down Expand Up @@ -74,7 +74,8 @@ fn parse_entropy<'a>(
let (_, values) = nom8::multi::separated_list1(
tag(","),
preceded(multispace0, nom8::bytes::complete::is_not(",")),
).parse(input)?;
)
.parse(input)?;

if values.len() < DETECT_ENTROPY_FIXED_PARAM_COUNT
|| values.len() > DETECT_ENTROPY_MAX_PARAM_COUNT
Expand Down Expand Up @@ -168,8 +169,7 @@ fn calculate_entropy(data: &[u8]) -> f64 {

#[no_mangle]
pub unsafe extern "C" fn SCDetectEntropyMatch(
c_data: *const c_void, length: i32, ctx: &DetectEntropyData,
calculated_entropy: *mut c_double,
c_data: *const c_void, length: i32, ctx: &DetectEntropyData, calculated_entropy: *mut c_double,
) -> bool {
if c_data.is_null() {
return false;
Expand Down
22 changes: 11 additions & 11 deletions rust/src/detect/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,18 +94,15 @@ pub fn parse_float_value<T: DetectFloatType>(input: &str) -> IResult<&str, T> {
// Handle numeric parsing, including scientific notation
map_opt(
recognize((
opt(alt((tag("+"), tag("-")))), // Handle optional signs
opt(alt((tag("+"), tag("-")))), // Handle optional signs
alt((digit1, recognize((tag("."), digit1)))), // Handle integers & `.5`
opt((tag("."), digit1)), // Handle decimals like `5.`
opt((
tag_no_case("e"),
opt(alt((tag("+"), tag("-")))),
digit1,
)), // Handle `1e10`, `-1e-5`
opt((tag("."), digit1)), // Handle decimals like `5.`
opt((tag_no_case("e"), opt(alt((tag("+"), tag("-")))), digit1)), // Handle `1e10`, `-1e-5`
)),
|float_str: &str| <T as DetectFloatType>::from_str(float_str),
),
)).parse(input)
))
.parse(input)
}
fn detect_parse_float_start_equal<T: DetectFloatType>(
i: &str,
Expand Down Expand Up @@ -133,7 +130,8 @@ pub fn detect_parse_float_start_interval<T: DetectFloatType>(
let (i, _) = opt(is_a(" ")).parse(i)?;
let (i, arg2) = verify(parse_float_value::<T>, |x| {
*x > arg1 && *x - arg1 > <T as FloatCore>::epsilon()
}).parse(i)?;
})
.parse(i)?;
let mode = if neg.is_some() {
DetectFloatMode::DetectFloatModeNegRg
} else {
Expand All @@ -150,7 +148,8 @@ fn detect_parse_float_mode(i: &str) -> IResult<&str, DetectFloatMode> {
value(DetectFloatMode::DetectFloatModeLt, tag("<")),
value(DetectFloatMode::DetectFloatModeNe, tag("!=")),
value(DetectFloatMode::DetectFloatModeEqual, tag("=")),
)).parse(i)?;
))
.parse(i)?;
Ok((i, mode))
}

Expand Down Expand Up @@ -223,7 +222,8 @@ fn detect_parse_float_notending<T: DetectFloatType>(i: &str) -> IResult<&str, De
detect_parse_float_start_interval,
detect_parse_float_start_equal,
detect_parse_float_start_symbol,
)).parse(i)?;
))
.parse(i)?;
Ok((i, float))
}

Expand Down
34 changes: 26 additions & 8 deletions rust/src/detect/iprep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ pub fn detect_parse_iprep(i: &str) -> IResult<&str, DetectIPRepData, RuleParseEr
let (_, values) = nom8::multi::separated_list1(
tag(","),
preceded(multispace0, nom8::bytes::complete::is_not(",")),
).parse(i)?;
)
.parse(i)?;

let args = values.len();
if args == 4 || args == 3 {
Expand Down Expand Up @@ -112,26 +113,43 @@ pub fn detect_parse_iprep(i: &str) -> IResult<&str, DetectIPRepData, RuleParseEr
arg2: 0,
mode,
};
return Ok((i, DetectIPRepData { du8, cat, cmd, isnotset: false, }));
return Ok((
i,
DetectIPRepData {
du8,
cat,
cmd,
isnotset: false,
},
));
} else {
let (isnotset, mode, arg1) = match values[2].trim() {
"isset" => { (false, DetectUintMode::DetectUintModeGte, 0) },
"isnotset" => { (true, DetectUintMode::DetectUintModeEqual, 0) },
_ => { return Err(make_error("invalid mode".to_string())); },
"isset" => (false, DetectUintMode::DetectUintModeGte, 0),
"isnotset" => (true, DetectUintMode::DetectUintModeEqual, 0),
_ => {
return Err(make_error("invalid mode".to_string()));
}
};
let du8 = DetectUintData::<u8> {
arg1,
arg2: 0,
mode,
};
return Ok((i, DetectIPRepData { du8, cat, cmd, isnotset, }));
return Ok((
i,
DetectIPRepData {
du8,
cat,
cmd,
isnotset,
},
));
}
} else if args < 3 {
return Err(make_error("too few arguments".to_string()));
} else {
} else {
return Err(make_error("too many arguments".to_string()));
}

}

#[no_mangle]
Expand Down
9 changes: 6 additions & 3 deletions rust/src/detect/requires.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ fn parse_op(input: &str) -> IResult<&str, VersionCompareOp> {
map(tag("<="), |_| VersionCompareOp::Lte),
map(tag("<"), |_| VersionCompareOp::Lt),
)),
).parse(input)
)
.parse(input)
}

/// Parse the next part of the version.
Expand All @@ -204,7 +205,8 @@ fn parse_next_version_part(input: &str) -> IResult<&str, u8> {
map_res(
take_till(|c| c == '.' || c == '-' || c == ' '),
|s: &str| s.parse::<u8>(),
).parse(input)
)
.parse(input)
}

/// Parse a version string into a SuricataVersion.
Expand All @@ -229,7 +231,8 @@ fn parse_key_value(input: &str) -> IResult<&str, (&str, &str)> {
let (input, key) = preceded(
multispace0,
take_while(|c: char| c.is_alphanumeric() || c == '-' || c == '_'),
).parse(input)?;
)
.parse(input)?;
let (input, value) = preceded(multispace0, take_till(|c: char| c == ',')).parse(input)?;
Ok((input, (key, value)))
}
Expand Down
12 changes: 3 additions & 9 deletions rust/src/detect/tojson/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,22 +74,16 @@ where
}

#[no_mangle]
pub unsafe extern "C" fn SCDetectU8ToJson(
js: &mut JsonBuilder, du: &DetectUintData<u8>,
) -> bool {
pub unsafe extern "C" fn SCDetectU8ToJson(js: &mut JsonBuilder, du: &DetectUintData<u8>) -> bool {
return detect_uint_to_json(js, du).is_ok();
}

#[no_mangle]
pub unsafe extern "C" fn SCDetectU16ToJson(
js: &mut JsonBuilder, du: &DetectUintData<u16>,
) -> bool {
pub unsafe extern "C" fn SCDetectU16ToJson(js: &mut JsonBuilder, du: &DetectUintData<u16>) -> bool {
return detect_uint_to_json(js, du).is_ok();
}

#[no_mangle]
pub unsafe extern "C" fn SCDetectU32ToJson(
js: &mut JsonBuilder, du: &DetectUintData<u32>,
) -> bool {
pub unsafe extern "C" fn SCDetectU32ToJson(js: &mut JsonBuilder, du: &DetectUintData<u32>) -> bool {
return detect_uint_to_json(js, du).is_ok();
}
3 changes: 2 additions & 1 deletion rust/src/detect/transforms/base64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ fn parse_transform_base64(
let (_, values) = nom8::multi::separated_list1(
tag(","),
preceded(multispace0, nom8::bytes::complete::is_not(",")),
).parse(input)?;
)
.parse(input)?;

// Too many options?
if values.len() > DETECT_TRANSFORM_BASE64_MAX_PARAM_COUNT {
Expand Down
4 changes: 2 additions & 2 deletions rust/src/detect/transforms/domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
use crate::detect::SIGMATCH_NOOPT;
use suricata_sys::sys::{
DetectEngineCtx, DetectEngineThreadCtx, InspectionBuffer, SCDetectHelperTransformRegister,
SCDetectSignatureAddTransform, SCTransformTableElmt, Signature, SCInspectionBufferCheckAndExpand,
SCInspectionBufferTruncate,
SCDetectSignatureAddTransform, SCInspectionBufferCheckAndExpand, SCInspectionBufferTruncate,
SCTransformTableElmt, Signature,
};

use std::os::raw::{c_int, c_void};
Expand Down
4 changes: 2 additions & 2 deletions rust/src/detect/transforms/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
use crate::detect::SIGMATCH_NOOPT;
use suricata_sys::sys::{
DetectEngineCtx, DetectEngineThreadCtx, InspectionBuffer, SCDetectHelperTransformRegister,
SCDetectSignatureAddTransform, SCTransformTableElmt, Signature, SCInspectionBufferCheckAndExpand,
SCInspectionBufferTruncate,
SCDetectSignatureAddTransform, SCInspectionBufferCheckAndExpand, SCInspectionBufferTruncate,
SCTransformTableElmt, Signature,
};

use crate::ffi::hashing::{G_DISABLE_HASHING, SC_SHA1_LEN, SC_SHA256_LEN};
Expand Down
2 changes: 1 addition & 1 deletion rust/src/detect/transforms/xor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ unsafe extern "C" fn xor_free(_de: *mut DetectEngineCtx, ctx: *mut c_void) {
std::mem::drop(Box::from_raw(ctx as *mut DetectTransformXorData));
}

unsafe extern "C" fn xor_id(data: *mut *const u8, length: *mut u32, ctx: *const c_void,) {
unsafe extern "C" fn xor_id(data: *mut *const u8, length: *mut u32, ctx: *const c_void) {
if data.is_null() || length.is_null() || ctx.is_null() {
return;
}
Expand Down
Loading
Loading