Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ env:
# A recent version of stable Rust that is known to pass build, test and other
# verification steps in this workflow. This was added because using "stable"
# could cause some steps to fail.
RUST_VERSION_KNOWN: "1.93.0"
RUST_VERSION_KNOWN: "1.98.0"

jobs:

Expand Down
22 changes: 22 additions & 0 deletions doc/userguide/firewall/firewall-design.rst
Original file line number Diff line number Diff line change
Expand Up @@ -356,3 +356,25 @@ Example for DNS::
# Accept all responses.
response-started: ["accept:tx"]


ARP handling in bridge mode
---------------------------

When running Suricata in bridge mode with a default deny policy, ARP packets are dropped by the
default ``packet.filter`` policy. In Suricata 8.0.x ARP detection is not available, so ARP
rules cannot be created. A global option can be used to automatically accept ARP packets
without requiring an explicit firewall rule for ARP.

The option is::

firewall:
policies:
accept-arp: yes

When ``accept-arp`` is enabled, ARP packets are accepted regardless of the default packet
filter policy. The default is ``no`` to preserve the existing deny-by-default behaviour.

This is a minimal, non-intrusive backport for the 8.0.x stable branch. In the main branch ARP
detection is available and ARP can be accepted via explicit rules, e.g.:

accept:packet arp:all any any -> any any (sid:1;)
6 changes: 2 additions & 4 deletions rust/src/detect/byte_math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,10 +350,8 @@ 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 {
return Err(make_error(format!("nbytes must be 1 through 4 (inclusive) when used with \"<<\" or \">>\"; {} is not valid", byte_math.nbytes)));
}
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
15 changes: 11 additions & 4 deletions rust/src/detect/datasets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

//! This module exposes items from the datasets C code to Rust.

use crate::ffi::hashing::{SC_MD5_LEN, SC_SHA256_LEN};
use base64::{self, Engine};
use std::ffi::{c_char, CStr};
use std::fs::{File, OpenOptions};
Expand Down Expand Up @@ -168,12 +169,15 @@ unsafe fn process_md5_set(
Ok(rs) => rs,
Err(_) => return -1,
};
if md5_string.len() != SC_MD5_LEN {
return -1;
}

if no_rep {
DatasetAdd(set, md5_string.as_ptr(), 16);
DatasetAdd(set, md5_string.as_ptr(), SC_MD5_LEN as u32);
} else if let Ok(val) = v[1].to_string().parse::<u16>() {
let rep: DataRepType = DataRepType { value: val };
DatasetAddwRep(set, md5_string.as_ptr(), 16, &rep);
DatasetAddwRep(set, md5_string.as_ptr(), SC_MD5_LEN as u32, &rep);
} else {
SCFatalErrorOnInit!(
"invalid datarep value {} in {}",
Expand All @@ -192,12 +196,15 @@ unsafe fn process_sha256_set(
Ok(rs) => rs,
Err(_) => return -1,
};
if sha256_string.len() != SC_SHA256_LEN {
return -1;
}

if no_rep {
DatasetAdd(set, sha256_string.as_ptr(), 32);
DatasetAdd(set, sha256_string.as_ptr(), SC_SHA256_LEN as u32);
} else if let Ok(val) = v[1].to_string().parse::<u16>() {
let rep: DataRepType = DataRepType { value: val };
DatasetAddwRep(set, sha256_string.as_ptr(), 32, &rep);
DatasetAddwRep(set, sha256_string.as_ptr(), SC_SHA256_LEN as u32, &rep);
} else {
SCFatalErrorOnInit!(
"invalid datarep value {} in {}",
Expand Down
4 changes: 2 additions & 2 deletions rust/src/detect/requires.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ pub unsafe extern "C" fn SCDetectRequiresStatusLog(
"rule was"
},
suricata_version,
&min_version
min_version
);
parts.push(msg);
}
Expand Down Expand Up @@ -445,7 +445,7 @@ pub unsafe extern "C" fn SCDetectRequiresStatusLog(
"rule was"
},
if status.feature_count > 1 { "s" } else { "" },
&features
features
);
parts.push(msg);
}
Expand Down
12 changes: 4 additions & 8 deletions rust/src/dhcp/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,8 @@ impl DHCPLogger {
{
#[allow(clippy::single_match)]
match code {
DHCP_OPT_TYPE => {
if !option.data.is_empty() {
return Some(option.data[0]);
}
DHCP_OPT_TYPE if !option.data.is_empty() => {
return Some(option.data[0]);
}
_ => {}
}
Expand Down Expand Up @@ -156,10 +154,8 @@ impl DHCPLogger {
self.log_opt_routers(js, option)?;
}
}
DHCP_OPT_VENDOR_CLASS_ID => {
if self.extended && !option.data.is_empty() {
js.set_string_from_bytes("vendor_class_identifier", &option.data)?;
}
DHCP_OPT_VENDOR_CLASS_ID if self.extended && !option.data.is_empty() => {
js.set_string_from_bytes("vendor_class_identifier", &option.data)?;
}
_ => {}
},
Expand Down
1 change: 0 additions & 1 deletion rust/src/dhcp/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,6 @@ pub fn parse_dhcp(input: &[u8]) -> IResult<&[u8], DHCPMessage> {

#[cfg(test)]
mod tests {
use crate::dhcp::dhcp::*;
use crate::dhcp::parser::*;

#[test]
Expand Down
6 changes: 3 additions & 3 deletions rust/src/http2/decompression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,15 @@ impl HTTP2DecoderHalf {
pub fn http2_encoding_fromvec(&mut self, input: &[u8]) {
//use first encoding...
if self.encoding == HTTP2ContentEncoding::Unknown {
if input == b"gzip" {
if input.eq_ignore_ascii_case(b"gzip") {
self.encoding = HTTP2ContentEncoding::Gzip;
self.decoder =
HTTP2Decompresser::Gzip(Box::new(GzDecoder::new(HTTP2cursor::new())));
} else if input == b"deflate" {
} else if input.eq_ignore_ascii_case(b"deflate") {
self.encoding = HTTP2ContentEncoding::Deflate;
self.decoder =
HTTP2Decompresser::Deflate(Box::new(DeflateDecoder::new(HTTP2cursor::new())));
} else if input == b"br" {
} else if input.eq_ignore_ascii_case(b"br") {
self.encoding = HTTP2ContentEncoding::Br;
self.decoder = HTTP2Decompresser::Brotli(Box::new(brotli::Decompressor::new(
HTTP2cursor::new(),
Expand Down
16 changes: 6 additions & 10 deletions rust/src/http2/detect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,8 @@ fn http2_tx_has_errorcode(
return 1;
}
}
HTTP2FrameTypeData::RSTSTREAM(rst) => {
if rst.errorcode == code {
return 1;
}
HTTP2FrameTypeData::RSTSTREAM(rst) if rst.errorcode == code => {
return 1;
}
_ => {}
}
Expand All @@ -95,10 +93,8 @@ fn http2_tx_has_errorcode(
return 1;
}
}
HTTP2FrameTypeData::RSTSTREAM(rst) => {
if rst.errorcode == code {
return 1;
}
HTTP2FrameTypeData::RSTSTREAM(rst) if rst.errorcode == code => {
return 1;
}
_ => {}
}
Expand Down Expand Up @@ -806,7 +802,7 @@ struct Http2ThreadBuf {

#[no_mangle]
pub unsafe extern "C" fn SCHttp2ThreadBufDataInit(_cfg: *mut c_void) -> *mut c_void {
let boxed = Box::new(Http2ThreadBuf::default());
let boxed = Box::<Http2ThreadBuf>::default();
return Box::into_raw(boxed) as *mut c_void;
}

Expand Down Expand Up @@ -951,7 +947,7 @@ struct Http2ThreadMultiBuf {

#[no_mangle]
pub unsafe extern "C" fn SCHttp2ThreadMultiBufDataInit(_cfg: *mut c_void) -> *mut c_void {
let boxed = Box::new(Http2ThreadMultiBuf::default());
let boxed = Box::<Http2ThreadMultiBuf>::default();
return Box::into_raw(boxed) as *mut c_void;
}

Expand Down
2 changes: 1 addition & 1 deletion rust/src/http2/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ fn log_http2_frames(frames: &[HTTP2Frame], js: &mut JsonBuilder) -> Result<bool,
js.start_object()?;
js.set_string(
"settings_id",
&format!("SETTINGS{}", &e.id.to_string().to_uppercase()),
&format!("SETTINGS{}", e.id.to_string().to_uppercase()),
)?;
js.set_uint("settings_value", e.value as u64)?;
js.close()?;
Expand Down
10 changes: 4 additions & 6 deletions rust/src/ike/detect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,10 @@ pub extern "C" fn SCIkeStateGetSaAttribute(
break;
}
}
IkeV2Transform::DH(ref e) => {
if sa == "alg_dh" {
ret_val = e.0 as u32;
ret_code = 1;
break;
}
IkeV2Transform::DH(ref e) if sa == "alg_dh" => {
ret_val = e.0 as u32;
ret_code = 1;
break;
}
_ => (),
}
Expand Down
6 changes: 2 additions & 4 deletions rust/src/jsonbuilder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ impl JsonBuilder {
// Reset the builder to its initial state, without losing
// the current capacity.
pub fn reset(&mut self) {
self.buf.truncate(0);
self.buf.clear();
self.state.clear();
match self.init_type {
Type::Array => {
Expand Down Expand Up @@ -1618,6 +1618,4 @@ static ESCAPED: [u8; 256] = [
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F
];

pub static HEX: [u8; 16] = [
b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'a', b'b', b'c', b'd', b'e', b'f',
];
pub static HEX: [u8; 16] = *b"0123456789abcdef";
12 changes: 4 additions & 8 deletions rust/src/mime/mime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,10 @@ pub fn mime_find_header_token<'a>(
// check for initial section of a parameter
current_section_slice.extend_from_slice(token);
current_section_slice.extend_from_slice(b"*0");
match t.tokens.get(&current_section_slice[..]) {
Some(value) => {
sections_values.extend_from_slice(value);
let l = current_section_slice.len();
current_section_slice[l - 1] = b'1';
}
None => return None,
}
let value = t.tokens.get(&current_section_slice[..])?;
sections_values.extend_from_slice(value);
let l = current_section_slice.len();
current_section_slice[l - 1] = b'1';
}
}

Expand Down
3 changes: 2 additions & 1 deletion rust/src/nfs/nfs3_records.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,8 @@ pub fn parse_nfs3_request_write(i: &[u8], complete: bool) -> IResult<&[u8], Nfs3
pub fn parse_nfs3_reply_read(i: &[u8], complete: bool) -> IResult<&[u8], NfsReplyRead<'_>> {
let (i, status) = be_u32(i)?;
let (i, attr_follows) = verify(be_u32, |&v| v <= 1)(i)?;
let (i, attr_blob) = take(84_usize)(i)?; // fixed size?
let (i, attr_blob_opt) = cond(attr_follows == 1, take(84_usize))(i)?;
let attr_blob = attr_blob_opt.unwrap_or(&[]);
let (i, count) = be_u32(i)?;
let (i, eof) = verify(be_u32, |&v| v <= 1)(i)?;
let (i, data_len) = verify(be_u32, |&v| v <= count)(i)?;
Expand Down
10 changes: 5 additions & 5 deletions rust/src/nfs/nfs4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,11 +380,11 @@ impl NFSState {
.put(rd.value.to_vec(), xidmap.file_name.to_vec());
}
}
Nfs4ResponseContent::PutRootFH(s) => {
if s == NFS4_OK && xidmap.file_name.is_empty() {
xidmap.file_name = b"<mount_root>".to_vec();
SCLogDebug!("filename {:?}", xidmap.file_name);
}
Nfs4ResponseContent::PutRootFH(s)
if s == NFS4_OK && xidmap.file_name.is_empty() =>
{
xidmap.file_name = b"<mount_root>".to_vec();
SCLogDebug!("filename {:?}", xidmap.file_name);
}
_ => {}
}
Expand Down
8 changes: 4 additions & 4 deletions rust/src/sdp/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,9 @@ fn parse_connection_data(i: &[u8]) -> IResult<&[u8], String> {

let mut connection_data = format!(
"{} {} {}",
&nettype,
&addrtype,
&connection_address.to_string()
nettype,
addrtype,
connection_address
);
if let Some(ttl) = ttl {
connection_data = format!("{}/{}", connection_data, ttl);
Expand Down Expand Up @@ -463,7 +463,7 @@ fn parse_media_description(i: &[u8]) -> IResult<&[u8], MediaDescription> {
} else {
format!("{}", port)
};
let mut media_str = format!("{} {} {}", &media, &port, &proto);
let mut media_str = format!("{} {} {}", media, port, proto);
if !fmt.is_empty() {
let fmt: Vec<String> = fmt.into_iter().map(String::from).collect();
media_str = format!("{} {}", media_str, fmt.join(" "));
Expand Down
2 changes: 1 addition & 1 deletion rust/src/ssh/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ pub struct SshPacketKeyExchange<'a> {
pub reserved: u32,
}

const SSH_HASSH_STRING_DELIMITER_SLICE: [u8; 1] = [b';'];
const SSH_HASSH_STRING_DELIMITER_SLICE: [u8; 1] = *b";";

impl SshPacketKeyExchange<'_> {
pub fn generate_hassh(
Expand Down
2 changes: 1 addition & 1 deletion rust/suricatasc/src/unix/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl Client {
{
let mut encoded = serde_json::to_string(&msg)?;
if self.verbose {
println!("SND: {}", &encoded);
println!("SND: {}", encoded);
}
encoded.push('\n');
self.socket.write_all(encoded.as_bytes())?;
Expand Down
6 changes: 3 additions & 3 deletions rust/suricatasc/src/unix/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {

let verbose = args.verbose;
if verbose {
println!("Using Suricata command socket: {}", &socket_filename);
println!("Using Suricata command socket: {}", socket_filename);
}

let client = match Client::connect(&socket_filename, verbose) {
Ok(client) => client,
Err(err) => {
eprintln!("Unable to connect socket to {}: {}", &socket_filename, err);
eprintln!("Unable to connect socket to {}: {}", socket_filename, err);
std::process::exit(1);
}
};
Expand Down Expand Up @@ -95,7 +95,7 @@ fn run_interactive(mut client: Client) -> Result<(), Box<dyn std::error::Error>>
break;
}
if let Err(err) = client.reconnect() {
println!("Error: {}", &err);
println!("Error: {}", err);
break;
} else {
retry = true;
Expand Down
1 change: 1 addition & 0 deletions src/app-layer-expectation.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ static ExpectationList *AppLayerExpectationRemove(IPPair *ipp,
{
CIRCLEQ_REMOVE(&exp_list->list, exp, entries);
AppLayerFreeExpectation(exp);
IPPairDecrUsecnt(ipp);
SC_ATOMIC_SUB(expectation_count, 1);
exp_list->length--;
if (exp_list->length == 0) {
Expand Down
Loading
Loading