Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected], [email protected],
[email protected]
Control: affects -1 + src:suricata
User: [email protected]
Usertags: pu
Dear stable release managers,
I'd like to hand in security patches for suricata 7.0.10-1+deb13u1
in Debian trixie patching all the open CVEs for suricata from November
2025. In accordance with the security team, the CVEs will not warrant
DSAs and should be included in the next point release please.
[ Reason ]
Security fixes for:
- CVE-2025-64344
- CVE-2025-64333
- CVE-2025-64332
- CVE-2025-64331
- CVE-2025-64330
[ Impact ]
Exploiting these CVEs can lead to reduced availability / crashes.
- CVE-2025-64344: Working with large buffers in Lua scripts can
lead to a stack overflow. Upstream severity MODERATE, but should
be patched though. [1]
- CVE-2025-64333: Logging a large HTTP content type can lead to a
stack overflow crashing suricata. [2]
- CVE-2025-64332: Enabled SWF decompression can lead to a stack
overflow crashing suricata. [3]
- CVE-2025-64331: Possible stack overflow crashing suricata when
logging the printable payload of large HTTP file transfers. [4]
- CVE-2025-64330: Possible heap overflow under certain circumstances
crashing suricata. [5]
As the impact may seem to look rather small, the vulnerabilities can be
exploited quite easily by simple sending the 'wrong' packets over the
network. Suricata is therefore highly affected due to its nature as an
IDS by processing untrusted input from the network.
[ Tests ]
- autopkgtest runs the unit-tests and these are OK for the patched
package.
- Furthermore I used suricata-verify, an upstream tool for additional
testing with pcaps, which also has the same number of successful tests
between deb13u1 and deb13u2. See stable [6] vs. patched [7].
[ Risks ]
Because of successful unit tests, the risk should be OK.
Not patching the vulnerabilities can lead to crashing detection and that
would miss the point of an IDS/IPS.
[ Checklist ]
[x] *all* changes are documented in the d/changelog
[x] I reviewed all changes and I approve them
[x] attach debdiff against the package in (old)stable
[x] the issue is verified as fixed in unstable
[ Changes ]
Applied the upstream patches for 7.0.10-13 fixing the CVEs.
One (CVE-2025-64331.patch) has to be appended by a C declaration for the
rust function SCJbSetPrintAsciiString, which was taken from the 7.0.13
release tarball of suricata.
Furthermore added Debian patch headers and changelog.
[ Other info ]
See source-debdiff and patches attached.
See the final branch at [8] which might be a bit easier to review,
because each change is documented as a single commit.
Thanks for your work!
[1] https://security-tracker.debian.org/tracker/CVE-2025-64344
[2] https://security-tracker.debian.org/tracker/CVE-2025-64333
[3] https://security-tracker.debian.org/tracker/CVE-2025-64332
[4] https://security-tracker.debian.org/tracker/CVE-2025-64331
[5] https://security-tracker.debian.org/tracker/CVE-2025-64330
[6] https://salsa.debian.org/ecite/pkg-suricata/-/jobs/8748285
[7] https://salsa.debian.org/ecite/pkg-suricata/-/jobs/8754054
[8] https://salsa.debian.org/ecite/pkg-suricata/-/tree/ecite/debian/trixie
diff --git a/debian/changelog b/debian/changelog
index 9cd0071f7..12c844bdd 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+suricata (1:7.0.10-1+deb13u2) trixie; urgency=medium
+
+ * Fix CVE-2025-64344 in 7.0.10.
+ Cherry-Picked from upstream a7ff4c9ba53009680c7cd128b16c28d0aeda9886.
+
+ -- Andreas Dolp <[email protected]> Wed, 10 Dec 2025 20:12:20 +0100
+
suricata (1:7.0.10-1+deb13u1) trixie; urgency=medium
* Fix CVE-2025-53538 in 7.0.10.
diff --git a/debian/patches/CVE-2025-64344.patch
b/debian/patches/CVE-2025-64344.patch
new file mode 100644
index 000000000..f74ce1083
--- /dev/null
+++ b/debian/patches/CVE-2025-64344.patch
@@ -0,0 +1,50 @@
+From a7ff4c9ba53009680c7cd128b16c28d0aeda9886 Mon Sep 17 00:00:00 2001
+From: Victor Julien <[email protected]>
+Date: Fri, 31 Oct 2025 09:38:55 +0100
+Subject: [PATCH] lua: remove luajit pushlstring workaround
+
+81ee6f5aadeb ("lua: push correct length back through ScFlowvarGet, work around
valgrind warning")
+added a workaround for valgrind warnings in pushing a string buffer
+into the lua state. This is no longer needed as tested with both
+address sanitizer and valgrind.
+
+(cherry picked from commit 52fd61dffdfa50c9a2d4ec24865a54da0b8f0a2a)
+
+Origin: upstream,
https://github.com/OISF/suricata/commit/a7ff4c9ba53009680c7cd128b16c28d0aeda9886.patch
+Bug: https://redmine.openinfosecfoundation.org/issues/8065
+Subject: Upstream fix for CVE-2025-64344
+---
+ src/util-lua.c | 17 +----------------
+ 1 file changed, 1 insertion(+), 16 deletions(-)
+
+diff --git a/src/util-lua.c b/src/util-lua.c
+index 9e65c3017..3dd1d3150 100644
+--- a/src/util-lua.c
++++ b/src/util-lua.c
+@@ -328,22 +328,7 @@ void LuaPrintStack(lua_State *state) {
+
+ int LuaPushStringBuffer(lua_State *luastate, const uint8_t *input, size_t
input_len)
+ {
+- if (input_len % 4 != 0) {
+- /* we're using a buffer sized at a multiple of 4 as lua_pushlstring
generates
+- * invalid read errors in valgrind otherwise. Adding in a nul to be
sure.
+- *
+- * Buffer size = len + 1 (for nul) + whatever makes it a multiple of
4 */
+- size_t buflen = input_len + 1 + ((input_len + 1) % 4);
+- uint8_t buf[buflen];
+- memset(buf, 0x00, buflen);
+- memcpy(buf, input, input_len);
+- buf[input_len] = '\0';
+-
+- /* return value through luastate, as a luastring */
+- lua_pushlstring(luastate, (char *)buf, input_len);
+- } else {
+- lua_pushlstring(luastate, (char *)input, input_len);
+- }
++ lua_pushlstring(luastate, (char *)input, input_len);
+ return 1;
+ }
+
+--
+2.51.2
+
diff --git a/debian/patches/series b/debian/patches/series
index 4a9099c67..0775dd558 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -10,3 +10,4 @@ avoid-to-include-if_tunnel-h.patch
llc.patch
CVE-2025-53538.patch
CVE-2025-59147.patch
+CVE-2025-64344.patch
diff --git a/debian/changelog b/debian/changelog
index 12c844bdd..12a270bfd 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,6 +2,8 @@ suricata (1:7.0.10-1+deb13u2) trixie; urgency=medium
* Fix CVE-2025-64344 in 7.0.10.
Cherry-Picked from upstream a7ff4c9ba53009680c7cd128b16c28d0aeda9886.
+ * Fix CVE-2025-64333 in 7.0.10.
+ Cherry-Picked from upstream 4b1d284bb57219b6677a8bda5cdc14a24a6aa22d.
-- Andreas Dolp <[email protected]> Wed, 10 Dec 2025 20:12:20 +0100
diff --git a/debian/patches/CVE-2025-64333.patch
b/debian/patches/CVE-2025-64333.patch
new file mode 100644
index 000000000..59b501359
--- /dev/null
+++ b/debian/patches/CVE-2025-64333.patch
@@ -0,0 +1,45 @@
+From 4b1d284bb57219b6677a8bda5cdc14a24a6aa22d Mon Sep 17 00:00:00 2001
+From: Philippe Antoine <[email protected]>
+Date: Thu, 30 Oct 2025 11:43:27 +0100
+Subject: [PATCH] output/http: log content-type like other headers
+
+Ticket: 8056
+
+Avoid stack allocation.
+Do not handle null and ; especially
+
+(cherry picked from commit b8411fcc8dfc16910c3080d4d8c03a9a64c3a1f7)
+
+Origin: upstream,
https://github.com/OISF/suricata/commit/4b1d284bb57219b6677a8bda5cdc14a24a6aa22d.patch
+Bug: https://redmine.openinfosecfoundation.org/issues/8056
+Subject: Upstream fix for CVE-2025-64333
+---
+ src/output-json-http.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/src/output-json-http.c b/src/output-json-http.c
+index bd3f6a116..87191caa9 100644
+--- a/src/output-json-http.c
++++ b/src/output-json-http.c
+@@ -237,13 +237,12 @@ static void EveHttpLogJSONBasic(JsonBuilder *js,
htp_tx_t *tx)
+ if (tx->response_headers != NULL) {
+ htp_header_t *h_content_type = htp_table_get_c(tx->response_headers,
"content-type");
+ if (h_content_type != NULL) {
+- const size_t size = bstr_len(h_content_type->value) * 2 + 1;
+- char string[size];
+- BytesToStringBuffer(bstr_ptr(h_content_type->value),
bstr_len(h_content_type->value), string, size);
+- char *p = strchr(string, ';');
++ uint32_t len = (uint32_t)bstr_len(h_content_type->value);
++ const uint8_t *p = memchr(bstr_ptr(h_content_type->value), ';',
len);
+ if (p != NULL)
+- *p = '\0';
+- jb_set_string(js, "http_content_type", string);
++ len = (uint32_t)(p - bstr_ptr(h_content_type->value));
++ jb_set_string_from_bytes(
++ js, "http_content_type", bstr_ptr(h_content_type->value),
len);
+ }
+ htp_header_t *h_content_range = htp_table_get_c(tx->response_headers,
"content-range");
+ if (h_content_range != NULL) {
+--
+2.51.2
+
diff --git a/debian/patches/series b/debian/patches/series
index 0775dd558..a2508d3ef 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -11,3 +11,4 @@ llc.patch
CVE-2025-53538.patch
CVE-2025-59147.patch
CVE-2025-64344.patch
+CVE-2025-64333.patch
diff --git a/debian/changelog b/debian/changelog
index 12a270bfd..c8e18cdc2 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -4,6 +4,8 @@ suricata (1:7.0.10-1+deb13u2) trixie; urgency=medium
Cherry-Picked from upstream a7ff4c9ba53009680c7cd128b16c28d0aeda9886.
* Fix CVE-2025-64333 in 7.0.10.
Cherry-Picked from upstream 4b1d284bb57219b6677a8bda5cdc14a24a6aa22d.
+ * Fix CVE-2025-64332 in 7.0.10.
+ Cherry-Picked from upstream f67d72702a2601d0a86ac1450686e70d7176f629.
-- Andreas Dolp <[email protected]> Wed, 10 Dec 2025 20:12:20 +0100
diff --git a/debian/patches/CVE-2025-64332.patch
b/debian/patches/CVE-2025-64332.patch
new file mode 100644
index 000000000..6d7e34c5a
--- /dev/null
+++ b/debian/patches/CVE-2025-64332.patch
@@ -0,0 +1,44 @@
+From f67d72702a2601d0a86ac1450686e70d7176f629 Mon Sep 17 00:00:00 2001
+From: Philippe Antoine <[email protected]>
+Date: Thu, 30 Oct 2025 11:27:22 +0100
+Subject: [PATCH] util/swf: move allocation from stack to heap
+
+As it can overflow the stack
+
+Ticket: 8055
+(cherry picked from commit a84addb771846f6d4d55ec535a4591f58369e49c)
+
+Origin: upstream,
https://github.com/OISF/suricata/commit/f67d72702a2601d0a86ac1450686e70d7176f629.patch
+Bug: https://redmine.openinfosecfoundation.org/issues/8055
+Subject: Upstream fix for CVE-2025-64332
+---
+ src/util-file-decompression.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/src/util-file-decompression.c b/src/util-file-decompression.c
+index dfafdc87f..bf65b0b7c 100644
+--- a/src/util-file-decompression.c
++++ b/src/util-file-decompression.c
+@@ -169,7 +169,10 @@ int FileSwfDecompression(const uint8_t *buffer, uint32_t
buffer_len,
+ * | LZMA properties | Uncompressed length | Compressed data |
+ */
+ compressed_data_len += 13;
+- uint8_t compressed_data[compressed_data_len];
++ uint8_t *compressed_data = SCCalloc(1, compressed_data_len);
++ if (compressed_data == NULL) {
++ goto error;
++ }
+ /* put lzma properties */
+ memcpy(compressed_data, buffer + 12, 5);
+ /* put lzma end marker */
+@@ -183,6 +186,7 @@ int FileSwfDecompression(const uint8_t *buffer, uint32_t
buffer_len,
+ r = FileSwfLzmaDecompression(det_ctx,
+ compressed_data, compressed_data_len,
+ out_buffer->buf + 8, out_buffer->len -
8);
++ SCFree(compressed_data);
+ if (r == 0)
+ goto error;
+ } else {
+--
+2.51.2
+
diff --git a/debian/patches/series b/debian/patches/series
index a2508d3ef..e42df8a22 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -12,3 +12,4 @@ CVE-2025-53538.patch
CVE-2025-59147.patch
CVE-2025-64344.patch
CVE-2025-64333.patch
+CVE-2025-64332.patch
diff --git a/debian/changelog b/debian/changelog
index c8e18cdc2..5d5e7c24b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -6,6 +6,9 @@ suricata (1:7.0.10-1+deb13u2) trixie; urgency=medium
Cherry-Picked from upstream 4b1d284bb57219b6677a8bda5cdc14a24a6aa22d.
* Fix CVE-2025-64332 in 7.0.10.
Cherry-Picked from upstream f67d72702a2601d0a86ac1450686e70d7176f629.
+ * Fix CVE-2025-64331 in 7.0.10.
+ Cherry-Picked from upstream 5abf9b81e78476f49ab074f3a74b5840747cd069.
+ Added missing function declaration and refreshed patch by quilt.
-- Andreas Dolp <[email protected]> Wed, 10 Dec 2025 20:12:20 +0100
diff --git a/debian/patches/CVE-2025-64331.patch
b/debian/patches/CVE-2025-64331.patch
new file mode 100644
index 000000000..ddd25fcbd
--- /dev/null
+++ b/debian/patches/CVE-2025-64331.patch
@@ -0,0 +1,259 @@
+From 5abf9b81e78476f49ab074f3a74b5840747cd069 Mon Sep 17 00:00:00 2001
+From: Philippe Antoine <[email protected]>
+Date: Thu, 30 Oct 2025 11:18:15 +0100
+Subject: [PATCH] output/jsonbuilder: helper function SCJbSetPrintAsciiString
+
+To replace C PrintStringsToBuffer and avoid a stack alloc
++ copy
+
+Ticket: 8004
+(cherry picked from commit 7447651fa0956ff4ce55283a51b4a9494ec8cc6a)
+
+Origin: upstream,
https://github.com/OISF/suricata/commit/5abf9b81e78476f49ab074f3a74b5840747cd069.patch
+Bug: https://redmine.openinfosecfoundation.org/issues/8004
+Subject: Upstream fix for CVE-2025-64331
+---
+ rust/src/jsonbuilder.rs | 60 +++++++++++++++++++++++++++++++++++++++++
+ src/output-json-alert.c | 15 +++--------
+ src/output-json-frame.c | 12 ++-------
+ src/output-json-http.c | 9 +------
+ src/output-json.c | 36 +++++--------------------
+ 5 files changed, 72 insertions(+), 60 deletions(-)
+
+--- a/rust/src/jsonbuilder.rs
++++ b/rust/src/jsonbuilder.rs
+@@ -527,6 +527,52 @@
+ }
+ }
+
++ /// Set a key with a string value taking only ascii-printable bytes.
++ /// Non-printable characters are replaced by a dot `.`, except
++ /// CR and LF which are escaped the regular json way \r and \n
++ pub fn set_print_ascii(&mut self, key: &str, val: &[u8]) -> Result<&mut
Self, JsonError> {
++ match self.current_state() {
++ State::ObjectNth => {
++ self.push(',')?;
++ }
++ State::ObjectFirst => {
++ self.set_state(State::ObjectNth);
++ }
++ _ => {
++ debug_validate_fail!("invalid state");
++ return Err(JsonError::InvalidState);
++ }
++ }
++ self.push('"')?;
++ self.push_str(key)?;
++ self.push_str("\":\"")?;
++ for &x in val.iter() {
++ match x {
++ b'\r' => {
++ self.push_str("\\r")?;
++ }
++ b'\n'=> {
++ self.push_str("\\n")?;
++ }
++ b'"'=> {
++ self.push_str("\\\"")?;
++ }
++ b'\\'=> {
++ self.push_str("\\\\")?;
++ }
++ _ => {
++ if !x.is_ascii() || x.is_ascii_control() {
++ self.push('.')?;
++ } else {
++ self.push(x as char)?;
++ }
++ }
++ }
++ }
++ self.push('"')?;
++ Ok(self)
++ }
++
+ /// Set a key and a string value (from bytes) on an object, with a
limited size
+ pub fn set_string_from_bytes_limited(&mut self, key: &str, val: &[u8],
limit: usize) -> Result<&mut Self, JsonError> {
+ let mut valtrunc = Vec::new();
+@@ -883,6 +929,20 @@
+ }
+ return false;
+ }
++
++#[no_mangle]
++pub unsafe extern "C" fn SCJbSetPrintAsciiString(
++ js: &mut JsonBuilder, key: *const c_char, bytes: *const u8, len: u32,
++) -> bool {
++ if bytes.is_null() || len == 0 {
++ return false;
++ }
++ if let Ok(key) = CStr::from_ptr(key).to_str() {
++ let val = std::slice::from_raw_parts(bytes, len as usize);
++ return js.set_print_ascii(key, val).is_ok();
++ }
++ return false;
++}
+
+ #[no_mangle]
+ pub unsafe extern "C" fn jb_set_base64(
+--- a/src/output-json-alert.c
++++ b/src/output-json-alert.c
+@@ -452,13 +452,7 @@
+ }
+
+ if (json_output_ctx->flags & LOG_JSON_PAYLOAD) {
+- uint8_t printable_buf[p->payload_len + 1];
+- uint32_t offset = 0;
+- PrintStringsToBuffer(printable_buf, &offset,
+- p->payload_len + 1,
+- p->payload, p->payload_len);
+- printable_buf[p->payload_len] = '\0';
+- jb_set_string(js, "payload_printable", (char *)printable_buf);
++ SCJbSetPrintAsciiString(js, "payload_printable", p->payload,
p->payload_len);
+ }
+ }
+
+@@ -764,11 +758,8 @@
+ }
+
+ if (json_output_ctx->flags & LOG_JSON_PAYLOAD) {
+- uint8_t printable_buf[cbd.payload->offset + 1];
+- uint32_t offset = 0;
+- PrintStringsToBuffer(printable_buf, &offset,
sizeof(printable_buf), cbd.payload->buffer,
+- cbd.payload->offset);
+- jb_set_string(jb, "payload_printable", (char *)printable_buf);
++ SCJbSetPrintAsciiString(
++ jb, "payload_printable", cbd.payload->buffer,
cbd.payload->offset);
+ }
+ return true;
+ }
+--- a/src/output-json-frame.c
++++ b/src/output-json-frame.c
+@@ -202,11 +202,7 @@
+
+ if (cbd.payload->offset) {
+ jb_set_base64(jb, "payload", cbd.payload->buffer,
cbd.payload->offset);
+- uint8_t printable_buf[cbd.payload->offset + 1];
+- uint32_t offset = 0;
+- PrintStringsToBuffer(printable_buf, &offset, sizeof(printable_buf),
cbd.payload->buffer,
+- cbd.payload->offset);
+- jb_set_string(jb, "payload_printable", (char *)printable_buf);
++ SCJbSetPrintAsciiString(jb, "payload_printable", cbd.payload->buffer,
cbd.payload->offset);
+ jb_set_bool(jb, "complete", complete);
+ }
+ }
+@@ -235,11 +231,7 @@
+ const uint32_t log_data_len = MIN(data_len, 256);
+ jb_set_base64(js, "payload", data, log_data_len);
+
+- uint8_t printable_buf[log_data_len + 1];
+- uint32_t o = 0;
+- PrintStringsToBuffer(printable_buf, &o, log_data_len + 1, data,
log_data_len);
+- printable_buf[log_data_len] = '\0';
+- jb_set_string(js, "payload_printable", (char *)printable_buf);
++ SCJbSetPrintAsciiString(js, "payload_printable", data, log_data_len);
+ #if 0
+ char pretty_buf[data_len * 4 + 1];
+ pretty_buf[0] = '\0';
+--- a/src/output-json-http.c
++++ b/src/output-json-http.c
+@@ -366,7 +366,6 @@
+ static void BodyPrintableBuffer(JsonBuilder *js, HtpBody *body, const char
*key)
+ {
+ if (body->sb != NULL && body->sb->region.buf != NULL) {
+- uint32_t offset = 0;
+ const uint8_t *body_data;
+ uint32_t body_data_len;
+ uint64_t body_offset;
+@@ -376,13 +375,7 @@
+ return;
+ }
+
+- uint8_t printable_buf[body_data_len + 1];
+- PrintStringsToBuffer(printable_buf, &offset,
+- sizeof(printable_buf),
+- body_data, body_data_len);
+- if (offset > 0) {
+- jb_set_string(js, key, (char *)printable_buf);
+- }
++ SCJbSetPrintAsciiString(js, key, body_data, body_data_len);
+ }
+ }
+
+--- a/src/output-json.c
++++ b/src/output-json.c
+@@ -210,22 +210,10 @@
+ PrintStringsToBuffer(keybuf, &offset,
+ sizeof(keybuf),
+ pv->key, pv->key_len);
+- uint32_t len = pv->value_len;
+- uint8_t printable_buf[len + 1];
+- offset = 0;
+- PrintStringsToBuffer(printable_buf, &offset,
+- sizeof(printable_buf),
+- pv->value, pv->value_len);
+- jb_set_string(js_vars, (char *)keybuf, (char *)printable_buf);
++ SCJbSetPrintAsciiString(js_vars, (char *)keybuf, pv->value,
pv->value_len);
+ } else {
+ const char *varname = VarNameStoreLookupById(pv->id,
VAR_TYPE_PKT_VAR);
+- uint32_t len = pv->value_len;
+- uint8_t printable_buf[len + 1];
+- uint32_t offset = 0;
+- PrintStringsToBuffer(printable_buf, &offset,
+- sizeof(printable_buf),
+- pv->value, pv->value_len);
+- jb_set_string(js_vars, varname, (char *)printable_buf);
++ SCJbSetPrintAsciiString(js_vars, varname, pv->value,
pv->value_len);
+ }
+ jb_close(js_vars);
+ }
+@@ -276,15 +264,9 @@
+ break;
+ }
+
+- uint32_t len = fv->data.fv_str.value_len;
+- uint8_t printable_buf[len + 1];
+- uint32_t offset = 0;
+- PrintStringsToBuffer(printable_buf, &offset,
+- sizeof(printable_buf),
+- fv->data.fv_str.value, fv->data.fv_str.value_len);
+-
+ jb_start_object(js_flowvars);
+- jb_set_string(js_flowvars, varname, (char
*)printable_buf);
++ SCJbSetPrintAsciiString(
++ js_flowvars, varname, fv->data.fv_str.value,
fv->data.fv_str.value_len);
+ jb_close(js_flowvars);
+ }
+ } else if (fv->datatype == FLOWVAR_TYPE_STR && fv->key != NULL) {
+@@ -300,15 +282,9 @@
+ sizeof(keybuf),
+ fv->key, fv->keylen);
+
+- uint32_t len = fv->data.fv_str.value_len;
+- uint8_t printable_buf[len + 1];
+- offset = 0;
+- PrintStringsToBuffer(printable_buf, &offset,
+- sizeof(printable_buf),
+- fv->data.fv_str.value, fv->data.fv_str.value_len);
+-
+ jb_start_object(js_flowvars);
+- jb_set_string(js_flowvars, (const char *)keybuf, (char
*)printable_buf);
++ SCJbSetPrintAsciiString(js_flowvars, (const char *)keybuf,
fv->data.fv_str.value,
++ fv->data.fv_str.value_len);
+ jb_close(js_flowvars);
+ } else if (fv->datatype == FLOWVAR_TYPE_INT) {
+ const char *varname = VarNameStoreLookupById(fv->idx,
+--- a/rust/dist/rust-bindings.h
++++ b/rust/dist/rust-bindings.h
+@@ -4898,6 +4898,11 @@
+ const uint8_t *bytes,
+ uint32_t len);
+
++bool SCJbSetPrintAsciiString(struct JsonBuilder *js,
++ const char *key,
++ const uint8_t *bytes,
++ uint32_t len);
++
+ bool jb_set_base64(struct JsonBuilder *js,
+ const char *key,
+ const uint8_t *bytes,
diff --git a/debian/patches/series b/debian/patches/series
index e42df8a22..e6e8bb1fa 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -13,3 +13,4 @@ CVE-2025-59147.patch
CVE-2025-64344.patch
CVE-2025-64333.patch
CVE-2025-64332.patch
+CVE-2025-64331.patch
diff --git a/debian/changelog b/debian/changelog
index 5d5e7c24b..13814f8ad 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -9,6 +9,8 @@ suricata (1:7.0.10-1+deb13u2) trixie; urgency=medium
* Fix CVE-2025-64331 in 7.0.10.
Cherry-Picked from upstream 5abf9b81e78476f49ab074f3a74b5840747cd069.
Added missing function declaration and refreshed patch by quilt.
+ * Fix CVE-2025-64330 in 7.0.10.
+ Cherry-Picked from upstream 5d6c24cc2ce6a390c0956b7ecb2c5efc47e72abc.
-- Andreas Dolp <[email protected]> Wed, 10 Dec 2025 20:12:20 +0100
diff --git a/debian/patches/CVE-2025-64330.patch
b/debian/patches/CVE-2025-64330.patch
new file mode 100644
index 000000000..fa98e31b7
--- /dev/null
+++ b/debian/patches/CVE-2025-64330.patch
@@ -0,0 +1,50 @@
+From 5d6c24cc2ce6a390c0956b7ecb2c5efc47e72abc Mon Sep 17 00:00:00 2001
+From: Juliana Fajardini <[email protected]>
+Date: Fri, 31 Oct 2025 21:38:12 -0700
+Subject: [PATCH] output/alert: fix alert index access for verdict
+
+The engine uses p.alerts.cnt as an index to access the packet alert that
+has the `pass` action for the verdict.
+For IDS/IPS mode, a `pass` will always be the last signature in the
+alert queue. However, that position could be either `p.alerts.cnt` or
+`p.alerts.cnt-1`, depending on whether the `pass` rule has the `alert`
+keyword or not.
+This patch fix corner-case scenarios of:
+- accessing an index out of boundaries
+- off-by-one access
+Without changing how the engine increments the alerts.cnt, as this is
+used in many places, and would be a more invasive change.
+It checks the two different scenarios, plus the case when there is only
+a single match as a silent `pass` rule.
+
+Bug #8021
+Bug #7630
+
+Origin: upstream,
https://github.com/OISF/suricata/commit/5d6c24cc2ce6a390c0956b7ecb2c5efc47e72abc.patch
+Bug: https://redmine.openinfosecfoundation.org/issues/8021
+Subject: Upstream fix for CVE-2025-64330
+---
+ src/output-json-alert.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/src/output-json-alert.c b/src/output-json-alert.c
+index 495b8285f..8c000cb2a 100644
+--- a/src/output-json-alert.c
++++ b/src/output-json-alert.c
+@@ -702,7 +702,12 @@ void EveAddVerdict(JsonBuilder *jb, const Packet *p)
+
+ } else if (PacketCheckAction(p, ACTION_DROP) && EngineModeIsIPS()) {
+ JB_SET_STRING(jb, "action", "drop");
+- } else if (p->alerts.alerts[p->alerts.cnt].action & ACTION_PASS) {
++ } else if (p->alerts.cnt == 0 ||
++ (p->alerts.cnt <= packet_alert_max &&
++ (p->alerts.alerts[p->alerts.cnt - 1].action &
++ (ACTION_PASS | ACTION_ALERT)) == (ACTION_PASS
| ACTION_ALERT)) ||
++ (p->alerts.cnt < packet_alert_max &&
++ p->alerts.alerts[p->alerts.cnt].action & ACTION_PASS))
{
+ JB_SET_STRING(jb, "action", "pass");
+ } else {
+ // TODO make sure we don't have a situation where this wouldn't work
+--
+2.51.2
+
diff --git a/debian/patches/series b/debian/patches/series
index e6e8bb1fa..bf99f825e 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -14,3 +14,4 @@ CVE-2025-64344.patch
CVE-2025-64333.patch
CVE-2025-64332.patch
CVE-2025-64331.patch
+CVE-2025-64330.patch
diff -Nru suricata-7.0.10/debian/changelog suricata-7.0.10/debian/changelog
--- suricata-7.0.10/debian/changelog 2025-09-27 19:43:45.000000000 +0000
+++ suricata-7.0.10/debian/changelog 2025-12-10 19:12:20.000000000 +0000
@@ -1,3 +1,19 @@
+suricata (1:7.0.10-1+deb13u2) trixie; urgency=medium
+
+ * Fix CVE-2025-64344 in 7.0.10.
+ Cherry-Picked from upstream a7ff4c9ba53009680c7cd128b16c28d0aeda9886.
+ * Fix CVE-2025-64333 in 7.0.10.
+ Cherry-Picked from upstream 4b1d284bb57219b6677a8bda5cdc14a24a6aa22d.
+ * Fix CVE-2025-64332 in 7.0.10.
+ Cherry-Picked from upstream f67d72702a2601d0a86ac1450686e70d7176f629.
+ * Fix CVE-2025-64331 in 7.0.10.
+ Cherry-Picked from upstream 5abf9b81e78476f49ab074f3a74b5840747cd069.
+ Added missing function declaration and refreshed patch by quilt.
+ * Fix CVE-2025-64330 in 7.0.10.
+ Cherry-Picked from upstream 5d6c24cc2ce6a390c0956b7ecb2c5efc47e72abc.
+
+ -- Andreas Dolp <[email protected]> Wed, 10 Dec 2025 20:12:20 +0100
+
suricata (1:7.0.10-1+deb13u1) trixie; urgency=medium
* Fix CVE-2025-53538 in 7.0.10.
diff -Nru suricata-7.0.10/debian/patches/CVE-2025-64330.patch
suricata-7.0.10/debian/patches/CVE-2025-64330.patch
--- suricata-7.0.10/debian/patches/CVE-2025-64330.patch 1970-01-01
00:00:00.000000000 +0000
+++ suricata-7.0.10/debian/patches/CVE-2025-64330.patch 2025-12-10
19:12:20.000000000 +0000
@@ -0,0 +1,50 @@
+From 5d6c24cc2ce6a390c0956b7ecb2c5efc47e72abc Mon Sep 17 00:00:00 2001
+From: Juliana Fajardini <[email protected]>
+Date: Fri, 31 Oct 2025 21:38:12 -0700
+Subject: [PATCH] output/alert: fix alert index access for verdict
+
+The engine uses p.alerts.cnt as an index to access the packet alert that
+has the `pass` action for the verdict.
+For IDS/IPS mode, a `pass` will always be the last signature in the
+alert queue. However, that position could be either `p.alerts.cnt` or
+`p.alerts.cnt-1`, depending on whether the `pass` rule has the `alert`
+keyword or not.
+This patch fix corner-case scenarios of:
+- accessing an index out of boundaries
+- off-by-one access
+Without changing how the engine increments the alerts.cnt, as this is
+used in many places, and would be a more invasive change.
+It checks the two different scenarios, plus the case when there is only
+a single match as a silent `pass` rule.
+
+Bug #8021
+Bug #7630
+
+Origin: upstream,
https://github.com/OISF/suricata/commit/5d6c24cc2ce6a390c0956b7ecb2c5efc47e72abc.patch
+Bug: https://redmine.openinfosecfoundation.org/issues/8021
+Subject: Upstream fix for CVE-2025-64330
+---
+ src/output-json-alert.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/src/output-json-alert.c b/src/output-json-alert.c
+index 495b8285f..8c000cb2a 100644
+--- a/src/output-json-alert.c
++++ b/src/output-json-alert.c
+@@ -702,7 +702,12 @@ void EveAddVerdict(JsonBuilder *jb, const Packet *p)
+
+ } else if (PacketCheckAction(p, ACTION_DROP) && EngineModeIsIPS()) {
+ JB_SET_STRING(jb, "action", "drop");
+- } else if (p->alerts.alerts[p->alerts.cnt].action & ACTION_PASS) {
++ } else if (p->alerts.cnt == 0 ||
++ (p->alerts.cnt <= packet_alert_max &&
++ (p->alerts.alerts[p->alerts.cnt - 1].action &
++ (ACTION_PASS | ACTION_ALERT)) == (ACTION_PASS
| ACTION_ALERT)) ||
++ (p->alerts.cnt < packet_alert_max &&
++ p->alerts.alerts[p->alerts.cnt].action & ACTION_PASS))
{
+ JB_SET_STRING(jb, "action", "pass");
+ } else {
+ // TODO make sure we don't have a situation where this wouldn't work
+--
+2.51.2
+
diff -Nru suricata-7.0.10/debian/patches/CVE-2025-64331.patch
suricata-7.0.10/debian/patches/CVE-2025-64331.patch
--- suricata-7.0.10/debian/patches/CVE-2025-64331.patch 1970-01-01
00:00:00.000000000 +0000
+++ suricata-7.0.10/debian/patches/CVE-2025-64331.patch 2025-12-10
19:12:20.000000000 +0000
@@ -0,0 +1,259 @@
+From 5abf9b81e78476f49ab074f3a74b5840747cd069 Mon Sep 17 00:00:00 2001
+From: Philippe Antoine <[email protected]>
+Date: Thu, 30 Oct 2025 11:18:15 +0100
+Subject: [PATCH] output/jsonbuilder: helper function SCJbSetPrintAsciiString
+
+To replace C PrintStringsToBuffer and avoid a stack alloc
++ copy
+
+Ticket: 8004
+(cherry picked from commit 7447651fa0956ff4ce55283a51b4a9494ec8cc6a)
+
+Origin: upstream,
https://github.com/OISF/suricata/commit/5abf9b81e78476f49ab074f3a74b5840747cd069.patch
+Bug: https://redmine.openinfosecfoundation.org/issues/8004
+Subject: Upstream fix for CVE-2025-64331
+---
+ rust/src/jsonbuilder.rs | 60 +++++++++++++++++++++++++++++++++++++++++
+ src/output-json-alert.c | 15 +++--------
+ src/output-json-frame.c | 12 ++-------
+ src/output-json-http.c | 9 +------
+ src/output-json.c | 36 +++++--------------------
+ 5 files changed, 72 insertions(+), 60 deletions(-)
+
+--- a/rust/src/jsonbuilder.rs
++++ b/rust/src/jsonbuilder.rs
+@@ -527,6 +527,52 @@
+ }
+ }
+
++ /// Set a key with a string value taking only ascii-printable bytes.
++ /// Non-printable characters are replaced by a dot `.`, except
++ /// CR and LF which are escaped the regular json way \r and \n
++ pub fn set_print_ascii(&mut self, key: &str, val: &[u8]) -> Result<&mut
Self, JsonError> {
++ match self.current_state() {
++ State::ObjectNth => {
++ self.push(',')?;
++ }
++ State::ObjectFirst => {
++ self.set_state(State::ObjectNth);
++ }
++ _ => {
++ debug_validate_fail!("invalid state");
++ return Err(JsonError::InvalidState);
++ }
++ }
++ self.push('"')?;
++ self.push_str(key)?;
++ self.push_str("\":\"")?;
++ for &x in val.iter() {
++ match x {
++ b'\r' => {
++ self.push_str("\\r")?;
++ }
++ b'\n'=> {
++ self.push_str("\\n")?;
++ }
++ b'"'=> {
++ self.push_str("\\\"")?;
++ }
++ b'\\'=> {
++ self.push_str("\\\\")?;
++ }
++ _ => {
++ if !x.is_ascii() || x.is_ascii_control() {
++ self.push('.')?;
++ } else {
++ self.push(x as char)?;
++ }
++ }
++ }
++ }
++ self.push('"')?;
++ Ok(self)
++ }
++
+ /// Set a key and a string value (from bytes) on an object, with a
limited size
+ pub fn set_string_from_bytes_limited(&mut self, key: &str, val: &[u8],
limit: usize) -> Result<&mut Self, JsonError> {
+ let mut valtrunc = Vec::new();
+@@ -883,6 +929,20 @@
+ }
+ return false;
+ }
++
++#[no_mangle]
++pub unsafe extern "C" fn SCJbSetPrintAsciiString(
++ js: &mut JsonBuilder, key: *const c_char, bytes: *const u8, len: u32,
++) -> bool {
++ if bytes.is_null() || len == 0 {
++ return false;
++ }
++ if let Ok(key) = CStr::from_ptr(key).to_str() {
++ let val = std::slice::from_raw_parts(bytes, len as usize);
++ return js.set_print_ascii(key, val).is_ok();
++ }
++ return false;
++}
+
+ #[no_mangle]
+ pub unsafe extern "C" fn jb_set_base64(
+--- a/src/output-json-alert.c
++++ b/src/output-json-alert.c
+@@ -452,13 +452,7 @@
+ }
+
+ if (json_output_ctx->flags & LOG_JSON_PAYLOAD) {
+- uint8_t printable_buf[p->payload_len + 1];
+- uint32_t offset = 0;
+- PrintStringsToBuffer(printable_buf, &offset,
+- p->payload_len + 1,
+- p->payload, p->payload_len);
+- printable_buf[p->payload_len] = '\0';
+- jb_set_string(js, "payload_printable", (char *)printable_buf);
++ SCJbSetPrintAsciiString(js, "payload_printable", p->payload,
p->payload_len);
+ }
+ }
+
+@@ -764,11 +758,8 @@
+ }
+
+ if (json_output_ctx->flags & LOG_JSON_PAYLOAD) {
+- uint8_t printable_buf[cbd.payload->offset + 1];
+- uint32_t offset = 0;
+- PrintStringsToBuffer(printable_buf, &offset,
sizeof(printable_buf), cbd.payload->buffer,
+- cbd.payload->offset);
+- jb_set_string(jb, "payload_printable", (char *)printable_buf);
++ SCJbSetPrintAsciiString(
++ jb, "payload_printable", cbd.payload->buffer,
cbd.payload->offset);
+ }
+ return true;
+ }
+--- a/src/output-json-frame.c
++++ b/src/output-json-frame.c
+@@ -202,11 +202,7 @@
+
+ if (cbd.payload->offset) {
+ jb_set_base64(jb, "payload", cbd.payload->buffer,
cbd.payload->offset);
+- uint8_t printable_buf[cbd.payload->offset + 1];
+- uint32_t offset = 0;
+- PrintStringsToBuffer(printable_buf, &offset, sizeof(printable_buf),
cbd.payload->buffer,
+- cbd.payload->offset);
+- jb_set_string(jb, "payload_printable", (char *)printable_buf);
++ SCJbSetPrintAsciiString(jb, "payload_printable", cbd.payload->buffer,
cbd.payload->offset);
+ jb_set_bool(jb, "complete", complete);
+ }
+ }
+@@ -235,11 +231,7 @@
+ const uint32_t log_data_len = MIN(data_len, 256);
+ jb_set_base64(js, "payload", data, log_data_len);
+
+- uint8_t printable_buf[log_data_len + 1];
+- uint32_t o = 0;
+- PrintStringsToBuffer(printable_buf, &o, log_data_len + 1, data,
log_data_len);
+- printable_buf[log_data_len] = '\0';
+- jb_set_string(js, "payload_printable", (char *)printable_buf);
++ SCJbSetPrintAsciiString(js, "payload_printable", data, log_data_len);
+ #if 0
+ char pretty_buf[data_len * 4 + 1];
+ pretty_buf[0] = '\0';
+--- a/src/output-json-http.c
++++ b/src/output-json-http.c
+@@ -366,7 +366,6 @@
+ static void BodyPrintableBuffer(JsonBuilder *js, HtpBody *body, const char
*key)
+ {
+ if (body->sb != NULL && body->sb->region.buf != NULL) {
+- uint32_t offset = 0;
+ const uint8_t *body_data;
+ uint32_t body_data_len;
+ uint64_t body_offset;
+@@ -376,13 +375,7 @@
+ return;
+ }
+
+- uint8_t printable_buf[body_data_len + 1];
+- PrintStringsToBuffer(printable_buf, &offset,
+- sizeof(printable_buf),
+- body_data, body_data_len);
+- if (offset > 0) {
+- jb_set_string(js, key, (char *)printable_buf);
+- }
++ SCJbSetPrintAsciiString(js, key, body_data, body_data_len);
+ }
+ }
+
+--- a/src/output-json.c
++++ b/src/output-json.c
+@@ -210,22 +210,10 @@
+ PrintStringsToBuffer(keybuf, &offset,
+ sizeof(keybuf),
+ pv->key, pv->key_len);
+- uint32_t len = pv->value_len;
+- uint8_t printable_buf[len + 1];
+- offset = 0;
+- PrintStringsToBuffer(printable_buf, &offset,
+- sizeof(printable_buf),
+- pv->value, pv->value_len);
+- jb_set_string(js_vars, (char *)keybuf, (char *)printable_buf);
++ SCJbSetPrintAsciiString(js_vars, (char *)keybuf, pv->value,
pv->value_len);
+ } else {
+ const char *varname = VarNameStoreLookupById(pv->id,
VAR_TYPE_PKT_VAR);
+- uint32_t len = pv->value_len;
+- uint8_t printable_buf[len + 1];
+- uint32_t offset = 0;
+- PrintStringsToBuffer(printable_buf, &offset,
+- sizeof(printable_buf),
+- pv->value, pv->value_len);
+- jb_set_string(js_vars, varname, (char *)printable_buf);
++ SCJbSetPrintAsciiString(js_vars, varname, pv->value,
pv->value_len);
+ }
+ jb_close(js_vars);
+ }
+@@ -276,15 +264,9 @@
+ break;
+ }
+
+- uint32_t len = fv->data.fv_str.value_len;
+- uint8_t printable_buf[len + 1];
+- uint32_t offset = 0;
+- PrintStringsToBuffer(printable_buf, &offset,
+- sizeof(printable_buf),
+- fv->data.fv_str.value, fv->data.fv_str.value_len);
+-
+ jb_start_object(js_flowvars);
+- jb_set_string(js_flowvars, varname, (char
*)printable_buf);
++ SCJbSetPrintAsciiString(
++ js_flowvars, varname, fv->data.fv_str.value,
fv->data.fv_str.value_len);
+ jb_close(js_flowvars);
+ }
+ } else if (fv->datatype == FLOWVAR_TYPE_STR && fv->key != NULL) {
+@@ -300,15 +282,9 @@
+ sizeof(keybuf),
+ fv->key, fv->keylen);
+
+- uint32_t len = fv->data.fv_str.value_len;
+- uint8_t printable_buf[len + 1];
+- offset = 0;
+- PrintStringsToBuffer(printable_buf, &offset,
+- sizeof(printable_buf),
+- fv->data.fv_str.value, fv->data.fv_str.value_len);
+-
+ jb_start_object(js_flowvars);
+- jb_set_string(js_flowvars, (const char *)keybuf, (char
*)printable_buf);
++ SCJbSetPrintAsciiString(js_flowvars, (const char *)keybuf,
fv->data.fv_str.value,
++ fv->data.fv_str.value_len);
+ jb_close(js_flowvars);
+ } else if (fv->datatype == FLOWVAR_TYPE_INT) {
+ const char *varname = VarNameStoreLookupById(fv->idx,
+--- a/rust/dist/rust-bindings.h
++++ b/rust/dist/rust-bindings.h
+@@ -4898,6 +4898,11 @@
+ const uint8_t *bytes,
+ uint32_t len);
+
++bool SCJbSetPrintAsciiString(struct JsonBuilder *js,
++ const char *key,
++ const uint8_t *bytes,
++ uint32_t len);
++
+ bool jb_set_base64(struct JsonBuilder *js,
+ const char *key,
+ const uint8_t *bytes,
diff -Nru suricata-7.0.10/debian/patches/CVE-2025-64332.patch
suricata-7.0.10/debian/patches/CVE-2025-64332.patch
--- suricata-7.0.10/debian/patches/CVE-2025-64332.patch 1970-01-01
00:00:00.000000000 +0000
+++ suricata-7.0.10/debian/patches/CVE-2025-64332.patch 2025-12-10
19:12:20.000000000 +0000
@@ -0,0 +1,44 @@
+From f67d72702a2601d0a86ac1450686e70d7176f629 Mon Sep 17 00:00:00 2001
+From: Philippe Antoine <[email protected]>
+Date: Thu, 30 Oct 2025 11:27:22 +0100
+Subject: [PATCH] util/swf: move allocation from stack to heap
+
+As it can overflow the stack
+
+Ticket: 8055
+(cherry picked from commit a84addb771846f6d4d55ec535a4591f58369e49c)
+
+Origin: upstream,
https://github.com/OISF/suricata/commit/f67d72702a2601d0a86ac1450686e70d7176f629.patch
+Bug: https://redmine.openinfosecfoundation.org/issues/8055
+Subject: Upstream fix for CVE-2025-64332
+---
+ src/util-file-decompression.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/src/util-file-decompression.c b/src/util-file-decompression.c
+index dfafdc87f..bf65b0b7c 100644
+--- a/src/util-file-decompression.c
++++ b/src/util-file-decompression.c
+@@ -169,7 +169,10 @@ int FileSwfDecompression(const uint8_t *buffer, uint32_t
buffer_len,
+ * | LZMA properties | Uncompressed length | Compressed data |
+ */
+ compressed_data_len += 13;
+- uint8_t compressed_data[compressed_data_len];
++ uint8_t *compressed_data = SCCalloc(1, compressed_data_len);
++ if (compressed_data == NULL) {
++ goto error;
++ }
+ /* put lzma properties */
+ memcpy(compressed_data, buffer + 12, 5);
+ /* put lzma end marker */
+@@ -183,6 +186,7 @@ int FileSwfDecompression(const uint8_t *buffer, uint32_t
buffer_len,
+ r = FileSwfLzmaDecompression(det_ctx,
+ compressed_data, compressed_data_len,
+ out_buffer->buf + 8, out_buffer->len -
8);
++ SCFree(compressed_data);
+ if (r == 0)
+ goto error;
+ } else {
+--
+2.51.2
+
diff -Nru suricata-7.0.10/debian/patches/CVE-2025-64333.patch
suricata-7.0.10/debian/patches/CVE-2025-64333.patch
--- suricata-7.0.10/debian/patches/CVE-2025-64333.patch 1970-01-01
00:00:00.000000000 +0000
+++ suricata-7.0.10/debian/patches/CVE-2025-64333.patch 2025-12-10
19:12:20.000000000 +0000
@@ -0,0 +1,45 @@
+From 4b1d284bb57219b6677a8bda5cdc14a24a6aa22d Mon Sep 17 00:00:00 2001
+From: Philippe Antoine <[email protected]>
+Date: Thu, 30 Oct 2025 11:43:27 +0100
+Subject: [PATCH] output/http: log content-type like other headers
+
+Ticket: 8056
+
+Avoid stack allocation.
+Do not handle null and ; especially
+
+(cherry picked from commit b8411fcc8dfc16910c3080d4d8c03a9a64c3a1f7)
+
+Origin: upstream,
https://github.com/OISF/suricata/commit/4b1d284bb57219b6677a8bda5cdc14a24a6aa22d.patch
+Bug: https://redmine.openinfosecfoundation.org/issues/8056
+Subject: Upstream fix for CVE-2025-64333
+---
+ src/output-json-http.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/src/output-json-http.c b/src/output-json-http.c
+index bd3f6a116..87191caa9 100644
+--- a/src/output-json-http.c
++++ b/src/output-json-http.c
+@@ -237,13 +237,12 @@ static void EveHttpLogJSONBasic(JsonBuilder *js,
htp_tx_t *tx)
+ if (tx->response_headers != NULL) {
+ htp_header_t *h_content_type = htp_table_get_c(tx->response_headers,
"content-type");
+ if (h_content_type != NULL) {
+- const size_t size = bstr_len(h_content_type->value) * 2 + 1;
+- char string[size];
+- BytesToStringBuffer(bstr_ptr(h_content_type->value),
bstr_len(h_content_type->value), string, size);
+- char *p = strchr(string, ';');
++ uint32_t len = (uint32_t)bstr_len(h_content_type->value);
++ const uint8_t *p = memchr(bstr_ptr(h_content_type->value), ';',
len);
+ if (p != NULL)
+- *p = '\0';
+- jb_set_string(js, "http_content_type", string);
++ len = (uint32_t)(p - bstr_ptr(h_content_type->value));
++ jb_set_string_from_bytes(
++ js, "http_content_type", bstr_ptr(h_content_type->value),
len);
+ }
+ htp_header_t *h_content_range = htp_table_get_c(tx->response_headers,
"content-range");
+ if (h_content_range != NULL) {
+--
+2.51.2
+
diff -Nru suricata-7.0.10/debian/patches/CVE-2025-64344.patch
suricata-7.0.10/debian/patches/CVE-2025-64344.patch
--- suricata-7.0.10/debian/patches/CVE-2025-64344.patch 1970-01-01
00:00:00.000000000 +0000
+++ suricata-7.0.10/debian/patches/CVE-2025-64344.patch 2025-12-10
19:12:20.000000000 +0000
@@ -0,0 +1,50 @@
+From a7ff4c9ba53009680c7cd128b16c28d0aeda9886 Mon Sep 17 00:00:00 2001
+From: Victor Julien <[email protected]>
+Date: Fri, 31 Oct 2025 09:38:55 +0100
+Subject: [PATCH] lua: remove luajit pushlstring workaround
+
+81ee6f5aadeb ("lua: push correct length back through ScFlowvarGet, work around
valgrind warning")
+added a workaround for valgrind warnings in pushing a string buffer
+into the lua state. This is no longer needed as tested with both
+address sanitizer and valgrind.
+
+(cherry picked from commit 52fd61dffdfa50c9a2d4ec24865a54da0b8f0a2a)
+
+Origin: upstream,
https://github.com/OISF/suricata/commit/a7ff4c9ba53009680c7cd128b16c28d0aeda9886.patch
+Bug: https://redmine.openinfosecfoundation.org/issues/8065
+Subject: Upstream fix for CVE-2025-64344
+---
+ src/util-lua.c | 17 +----------------
+ 1 file changed, 1 insertion(+), 16 deletions(-)
+
+diff --git a/src/util-lua.c b/src/util-lua.c
+index 9e65c3017..3dd1d3150 100644
+--- a/src/util-lua.c
++++ b/src/util-lua.c
+@@ -328,22 +328,7 @@ void LuaPrintStack(lua_State *state) {
+
+ int LuaPushStringBuffer(lua_State *luastate, const uint8_t *input, size_t
input_len)
+ {
+- if (input_len % 4 != 0) {
+- /* we're using a buffer sized at a multiple of 4 as lua_pushlstring
generates
+- * invalid read errors in valgrind otherwise. Adding in a nul to be
sure.
+- *
+- * Buffer size = len + 1 (for nul) + whatever makes it a multiple of
4 */
+- size_t buflen = input_len + 1 + ((input_len + 1) % 4);
+- uint8_t buf[buflen];
+- memset(buf, 0x00, buflen);
+- memcpy(buf, input, input_len);
+- buf[input_len] = '\0';
+-
+- /* return value through luastate, as a luastring */
+- lua_pushlstring(luastate, (char *)buf, input_len);
+- } else {
+- lua_pushlstring(luastate, (char *)input, input_len);
+- }
++ lua_pushlstring(luastate, (char *)input, input_len);
+ return 1;
+ }
+
+--
+2.51.2
+
diff -Nru suricata-7.0.10/debian/patches/series
suricata-7.0.10/debian/patches/series
--- suricata-7.0.10/debian/patches/series 2025-09-27 19:43:45.000000000
+0000
+++ suricata-7.0.10/debian/patches/series 2025-12-10 19:12:20.000000000
+0000
@@ -10,3 +10,8 @@
llc.patch
CVE-2025-53538.patch
CVE-2025-59147.patch
+CVE-2025-64344.patch
+CVE-2025-64333.patch
+CVE-2025-64332.patch
+CVE-2025-64331.patch
+CVE-2025-64330.patch