Commit Graph

19464 Commits (928ac012156fb8d393ce5ac4a496fde3c2e87b00)
 

Author SHA1 Message Date
Victor Julien 928ac01215 ssl: fix SSLv2 CLIENT_HELLO underflow
SSLv2Decode() consumed six fixed CLIENT_HELLO body bytes (version +
cipher_spec_length + session_id_length) guarded only by input_len >= 6,
which checks the buffer remainder but not the record itself.  When an
attacker sends a record whose declared record_length is < 7 (e.g. 1),
bytes_processed advances past record_lengths_length + record_length,
leading an integer underflow.

Address by adding a record_length >= 7 check to the CLIENT_HELLO case.

Also add another check: bail if bytes_processed > record_length +
record_lengths_length.

Ticket: #8853.
6 days ago
Victor Julien 201ecd5618 tls: JA3 buffer pointers on allocation failure
Improper pointer handling would leave dangling pointers after allocation
failure that could get freed again (double free).

Ticket: #8857.
6 days ago
Victor Julien 8e4d49df0d github-ci: remove Debian 11 build; Debian 11 is EOL 6 days ago
Jason Ish 491259842b psl: update to 2.1.228
Ticket: 8147
7 days ago
Urval Kheni b475cc25b6 util: fix fallback memrchr() implementation
The fallback memrchr() implementation initialized the search pointer to
the one-past-end position and dereferenced it before decrementing, which
is undefined behavior in C.

Update the implementation to decrement the pointer before dereferencing
while preserving memrchr() semantics. Compare bytes using unsigned char
semantics to ensure values with the high bit set are handled correctly.

Refactor the fallback into a local SCMemrchrFallback() helper so it can
be exercised by unit tests on platforms that provide a native memrchr()
implementation.

Expand the unit test to cover first, middle, last, duplicate, single-byte,
zero-length, absent-element, and high-byte values.

Ticket: 9010

Signed-off-by: Urval Kheni <kheniurval777@gmail.com>
7 days ago
Philippe Antoine c608165c04 rfb: keep failure_reason as Vec<u8>
And log it with from_utf8_lossy

Since we may now cut a too big failure_reason breaking a valid
utf-8 string

Ticket: 8731
7 days ago
Philippe Antoine f9515dc71d rfb: limit strings length
Ticket: 8731

Adds a configurable limit to string lengths to avoid to retain
too much memory for too long, and avoid producing log events
that are too big
7 days ago
Lukas Sismis 3f0d99d9c2 fw: document config action in FW mode 7 days ago
Lukas Sismis 17e2e7f892 fw: disallow config to be used as a default policy
Ticket: 8954
7 days ago
Lukas Sismis d6521adf4e fw: allow pass as a secondary action only for accept
Previously, hook sequences in both rules and default policies
allowed `pass` to be combined with incompatible hooks (e.g.
reject or drop).

This commit clamps pass to accept only.

Ticket: 8954
7 days ago
Lukas Sismis 4bafe61ecf fw: validate scope inheritance in policies and rules
A secondary action given without an explicit scope inherits the scope of
the primary action, but was never validated against the scopes it
supports itself. `pass` only supports packet and flow scope but
the inheritance was never verified.

Ticket: 8954
7 days ago
Lukas Sismis 25ece1ed38 fw: respect configured policies in the rule analysis output
Some firewall rule analysis output had hardcoded paths.
This commit is querying respective tables and uses the actual
values.

Ticket: 8951
7 days ago
Jason Ish 51ac40009f smtp: recover from rejected BDAT commands
A server can reject a BDAT command before the client sends the
advertised chunk. Suricata would keep waiting for those bytes and treat
the rest of the SMTP session as chunk data.

Keeps subsequent SMTP commands and message data in sync with the
server.

Ticket: 8995
1 week ago
Philippe Antoine 9747f2fbde fuzz: limit packet payload allocation
To detect bug like 8856 of overread, which did not trigger
ASAN as we alloc default-packet-size or MAX_PAYLOAD_SIZE
for each packet, instead of just what we need
1 week ago
Andreas Dolp 011f52379c unix-socket: close socket and remove socket file on shutdown
Suricata never removed the unix command socket file after shutdown.
The socket path (sockettarget) is now preserved in the struct
UnixCommand_, because it is needed on shutdown to close the socket.

The cleanup is done in the shutdown path of UnixManager(), which is
reached uniformly whether shutdown is triggered by a fatal error or
a signal (e.g. SIGTERM) via THV_KILL. This also applies for a clean
shutdown via 'suricatasc -c shutdown'.

Ticket: 8799
1 week ago
dependabot[bot] b8084b37cb github-actions: bump github/codeql-action/upload-sarif
Bumps [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) from 1cd4d01d58f636bbdbffbfd3c121b3446d07e9f3 to a0c73122a6231d3a72b4b04036548af1cd2487c9.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](1cd4d01d58...a0c73122a6)

---
updated-dependencies:
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: a0c73122a6231d3a72b4b04036548af1cd2487c9
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
1 week ago
dependabot[bot] ba10f5177d github-actions: bump github/codeql-action from 4.37.3 to 4.37.9
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.37.3 to 4.37.9.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v4.37.3...v4.37.9)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.37.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 week ago
dependabot[bot] 28bcc96fe5 github-actions: bump vmactions/freebsd-vm from 1.5.2 to 1.5.5
Bumps [vmactions/freebsd-vm](https://github.com/vmactions/freebsd-vm) from 1.5.2 to 1.5.5.
- [Release notes](https://github.com/vmactions/freebsd-vm/releases)
- [Commits](77ed28d336...f0552d3b69)

---
updated-dependencies:
- dependency-name: vmactions/freebsd-vm
  dependency-version: 1.5.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
1 week ago
Jeff Lucovsky 9cffa8ab49 output/alert: tolerate a reference with no key
Substitute an empty string for a NULL key or reference in
AlertJsonReference() before the write, so the output no longer depends
on what a libc does with a null pointer and "%s", which the standard
leaves undefined. glibc prints "(null)"; nothing requires that.

Assert both are set alongside the substitution. DetectReferenceParse()
is the only producer of DetectReference and sets each string with its
length, so the assert cannot fire today -- it names the invariant for a
second producer that does not hold it, while the substitution covers a
release build, where DEBUG_VALIDATE_BUG_ON compiles out.

A release build that reaches the substitution logs whichever half it
has rather than crashing, and nothing records that it happened.

Issue: 8849
1 week ago
Jeff Lucovsky 6216f9262c detect/reference: set key on the unknown-key path
Assign ref->key for a reference key that is not in reference.config, so
the fallback that registers a synthetic entry produces the same key and
key_len as an ordinary lookup. The assignment sat in the branch taken
when SCRConfGetReference() found the key; the fallback registered the
entry, looked it up again, and fell through with ref->key still at the
NULL SCCalloc() left.

AlertJsonReference() passed that key to snprintf() with "%s%s" and
sized the destination from key_len. With key NULL and key_len 0, a rule
carrying reference:unknownkey,001-2010 logged "(null)001-" on glibc,
and handed a null pointer to a "%s" conversion, which the standard
leaves undefined.

Invert the lookup test so the add-and-retry runs when the lookup fails
and both paths reach one assignment. The comment on that assignment
named REFERENCE_SYSTEM_NAME_MAX; the string copied is a URL, bound by
REFERENCE_CONTENT_NAME_MAX.

DetectReferenceParseTest03() loaded a rule with an unknown key and
checked only that the signature parsed, which it did throughout. Check
the resolved key, its length, and the reference value.

Issue: 8849
1 week ago
Philippe Antoine 0b0606b126 http2: log :authority header as hostname
Ticket: 8774
1 week ago
Philippe Antoine f5e44ced1e http2: use host header for http.host keyword
if :authority header is absent

Ticket: 8774
1 week ago
Lukas Sismis d7bf52e71c doc: update Rust installation instructions
Rust website has changed the location of the installer.
Additionally their installer now includes automatic append to
.bashrc to source the correct path to Rust binaries.

Cbindgen as an instruction is also removed as it is not needed
when building from the downloaded and packaged Suricata.

Ticket: 8344
1 week ago
Jeff Lucovsky cd7f7751d5 suricata: bound stack trace formatting in signal handler
The crash handler built its stack trace by advancing a pointer with
the snprintf return value. That value is the length the output would
have had, not what was written, so once the trace filled msg the
pointer moved past the end of the buffer. Every size argument after
that, SC_LOG_MAX_LOG_MSG_LEN - (temp - msg), was negative and
converted to a huge size_t, and snprintf went on writing into the
stack past msg. With a deep enough stack the handler faults before it
can log the crash it exists to report.

The frame name lookup also compared unw_get_proc_name() against
UNW_ENOMEM, but libunwind returns the negated code, so the test
never fired. A lookup that failed with UNW_ENOINFO fell through
to the success branch and printed the name buffer, which
libunwind had not written.

Track space used with offset and use that on each snprintf call. Advance
by MIN(cw, remaining - 1) to prevent overruns.  The loop stops when
the buffer is full and closes the trace with "..." so a clipped message
is not read as a whole stack.

Failed symbol lookups now print "[unknown]:". -UNW_ENOMEM is not one of
them, since libunwind returns a truncated but usable name with it.
name starts as "?" so nothing is printed from it either way.

Ticket: 8846
2 weeks ago
Victor Julien 9b491a131e nfs: fix SECINFO_NO_NAME parser handling
nfs4_res_secinfo_no_name() used a local var "i2" to walk through
the security-flavor array entries, but returned the pre-walk var "i"
in the Ok at the end. Every byte of the flavor array was therefore left
unconsumed in the input stream and re-interpreted by count next iteration
as a subsequent compound operation.

Addressed by returning i2 instead of i so all flavor bytes are consumed.

Ticket: #8860.
2 weeks ago
Victor Julien 8e493e2d6c mpm/ac: fix PID mask in SCACSearch u32 branch
Lookup code used a different mask than the construct code.

Ticket: #8820.
2 weeks ago
Victor Julien c3b9cad5dd mpm/ac-ks: fix state index truncation in SCACTileSearchLarge
SCACTileSearchLarge uses 32-bit next-state cells holding a 24-bit state
index. When there are more than 65536 states, CheckMatch was called with
(uint16_t)state, silently discarding the bits beyond 16.

Address this by widening CheckMatch's state parameter.

Ticket: #8841.
2 weeks ago
Philippe Antoine b0b353d0c0 http2: host normalization handles ipv6 address
And does not consider automatically a port after first colon

Ticket: 8778
2 weeks ago
Philippe Antoine 52c01543c9 http2: code cleanup for http2_normalize_host
Just separate the steps in parsing, and deduplicate code
2 weeks ago
Victor Julien e41ccf837e pppoe: fix session over-read in DecodePPPOESession
Prevent out-of-bounds read of protocol field when PPPoE session header is
exactly PPPOE_SESSION_HEADER_MIN_LEN bytes. Inspect first protocol octet
only to decide single vs double octet form, and read second octet only after
len >= 8 verification.

Add unit tests for the 7-byte boundary case for both the double-octet
(rejected as too small) and single-octet (decoded as PPP_IP) protocols.

Ticket: #8856.
2 weeks ago
Lukas Sismis 7ca9471145 logging: prevent double-free multi-threaded logging
When multithreaded output was enabled, all threads freed
shallow-copy of sensor and prefix names.

This commit adds a guard so that only the parent frees the
allocated buffers.

Ticket: 8861
2 weeks ago
Stephen Donnelly 3d42f7cf63 source/erf: Handle ERF META and PAD record types and extension headers
Add support for ERF record types META and PAD, plus additional ETH types.

Add support for ERF extension headers.

These types and extension headers were already supported by erf-source-dag.

Made source-erf-file and source-erf-dag more consistent.

Ticket: 8962
2 weeks ago
Stephen Donnelly c6dd80f787 erf/file: Don't trust ERF wlen and rlen from input file
When reading an ERF file do not trust the ERF header values.

Do not use wlen to set packet length.

Ticket: 8836

Read rlen bytes into MAX_PAYLOAD_SIZE buffer.
Use PacketCopyData() to safely update p.

Ticket: 8865
2 weeks ago
Victor Julien d7c3aeda3c mpm/ac-ks: fix integer overflow in delta table size calc
In very large rulesets with lots of different patterns the
size calculation could overflow.

Ticket: #8844.
2 weeks ago
Jeff Lucovsky 4a647784c7 doc/bytemath: document the result of wide shifts
Record that << and >> yield 0 when rvalue is 64 or more, beside the
existing note about division by zero. A shift count can come from a
byte_extract variable, so the rule text alone does not say which
counts land in that case.

Issue: 8845
2 weeks ago
Jeff Lucovsky 89d09c457c detect/bytemath: reject literal shift counts of 64
Fail rule load when byte_math pairs << or >> with a literal rvalue of
64 or more. rvalue was bounded only to u32::MAX, so a rule shifting by
100 loaded and then produced 0 for every packet it inspected, spending
detection work on a comparison whose outcome was settled before the
first packet arrived.

A variable rvalue still loads. Its value comes from a byte_extract on
the packet and is not known until the rule runs, so the guard in
DetectByteMathDoMatch() stays the only check covering that path.

DetectByteMathParse() reports every SCByteMathParse() failure as
"invalid bytemath values", so the rejected rule is named by the
"error parsing signature" line that follows rather than by the reason
the parser gave.

Issue: 8845
2 weeks ago
Jeff Lucovsky e5d035fd16 detect/bytemath: guard right shift against wide counts
Zero the result when a byte_math right shift count reaches 64, the
width of the uint64_t being shifted, so the operation no longer
depends on behavior C11 6.5.7p3 leaves undefined. The left shift case
has done this since 473ca6dcf4; the right shift case was left
unguarded.

DetectByteMathDoMatch() shifted by whatever count it was handed. On
x86_64 the hardware masks the count to its low six bits, so a count of
64 became a shift of 0 and returned the extracted value unchanged
instead of 0. That value is stored in det_ctx->byte_values[] and feeds
any byte_test, isdataat, or content offset later in the signature, so
the signature's verdict follows from an arithmetic result the standard
does not define.

The count reaches the shift from the wire. When byte_math names a
variable for rvalue, DetectEngineContentInspectionInternal() reads it
out of det_ctx->byte_values[] at
detect-engine-content-inspection.c:614, where a preceding byte_extract
stored bytes taken from the payload, so one payload byte of 0x40 sets
the count to 64.

Issue: 8845
2 weeks ago
Shivani Bhardwaj 389700eca2 flow/rate: fix ring flushing
The fn to flush the ring is supposed to flush the entire ring buffer but
it only resets the buffer up to the "length" bytes. Fix this calculation
to correctly reflect the number of bytes that need to be reset.

Ticket: 8826
2 weeks ago
Victor Julien 54504ed13c affinity: handle NULL set name from --set affinity path
Setting a cpu-affinity path with --set, like

  --set threading.cpu-affinity.worker-cpu-set.threads=28

creates an intermediate node under cpu-affinity whose val is NULL.

With a legacy list format cpu-affinity, AffinitySetupLoadFromConfig()
red the set name from the node val and passed it to
GetAffinitySetName(), which then dereferenced the NULL pointer.

Address it by simply checking for the NULL.

Ticket: #6735.
2 weeks ago
Philippe Antoine 7c669548cb nfs: optionally parse nfs3 read attr-follows
Ticket: 8750
2 weeks ago
Philippe Antoine c9434b3703 detect/frame: fix assert
A rule like `frame:http1.response; to_md5;` could have a buffer
bigger than the frame

Ticket: 8763
2 weeks ago
Philippe Antoine 7c394b9774 datasets: add size checks for hashes read
Ticket: 8768
2 weeks ago
Lukas Sismis 092ae272e2 firewall: validate action scope against the hook class
Validate the resolved scope against the class of hook it is being applied
to and fail at startup if it does not fit.

Ticket: 8712
3 weeks ago
Lukas Sismis 0aaa80d4f3 firewall: add default-policy to policy config
Every hook has a built-in default policy, but expressing anything other
than the built-in meant naming each hook explicitly.
This commit adds a `default-policy` setting that covers all hooks below it.
For any hook the most specific setting present wins.

DoParseAppSubStatePolicy() collapses into DoParseAppPolicy() as a sub state
hook only differs by an extra path segment.

Ticket: 8712
3 weeks ago
Lukas Sismis 1aa0259876 firewall: share the generic app hook name helper
Mapping an app-layer progress state to its generic request-/response-
hook alias was hardcoded in multiple places.

This commit adds a wrapper to unify it to a single function.
It returns the config-form (hyphenated) name, or NULL for an
intermediate state.

Ticket: 8712
3 weeks ago
Jason Ish acd9d3a09e github-ci: update rust known version to 1.98.0 3 weeks ago
Jason Ish 99f7b1f437 dhcp: remove unused import in test
To address clippy warning.
3 weeks ago
Juliana Fajardini 34b7a9ef82 scripts: check doc rules as TD and FW rules
Previously, a rule that had firewall-only syntax or keywords would fail
the script check.

Since we can't guarantee that a firewall rule will look different than a
detection one, run rule examples against both scenarios before failing
them.
3 weeks ago
Juliana Fajardini f3e27b0e41 scripts: check-doc-rules tries local bin first
If the point is to check the docs for added changes, it makes sense to
that used binary is the one that comes with the doc changes. Thus, try
using the local binary first, before falling back to usr/bin installed
Suricata.
3 weeks ago
Yash Datre 398687d5d4 detect: add tcp.session keyword for unified TCP lifecycle matching
Introduce the tcp.session: keyword that accepts a comma-separated subset
of {setup, established, closing} and matches packets whose TCP session
state falls within the named phases.

This lets a rule writer cover the full TCP lifecycle in one rule instead
of separate flow:not_established + flow:established rules.

Changes:
- New detect-tcp-session.{c,h} with parser, match function, unit tests
- Register DETECT_TCP_SESSION in detect-engine-register.{c,h}
- Add to Makefile.am source list
- Extend engine-analyzer text output for tcp.session:
- Extend firewall.json keyword_info with tcp_session phase values
- Update flow-keywords.rst documentation
- Require TCP protocol and SIG_FLAG_REQUIRE_PACKET at setup

Ticket: 7704
3 weeks ago